FrontendAction.cpp revision b0f4b9a558933b307073f7cd7753602f94354ae9
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/Lex/HeaderSearch.h" 154ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "clang/Lex/Preprocessor.h" 164ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "clang/Frontend/ASTUnit.h" 174ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "clang/Frontend/CompilerInstance.h" 184ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h" 195aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber#include "clang/Frontend/FrontendPluginRegistry.h" 205aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber#include "clang/Frontend/MultiplexConsumer.h" 2119510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Parse/ParseAST.h" 22b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis#include "clang/Serialization/ASTDeserializationListener.h" 23b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis#include "clang/Serialization/ChainedIncludesSource.h" 244ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "llvm/Support/MemoryBuffer.h" 254ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "llvm/Support/Timer.h" 264ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "llvm/Support/ErrorHandling.h" 274ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar#include "llvm/Support/raw_ostream.h" 284ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbarusing namespace clang; 294ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 30b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidisnamespace { 31b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 32b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis/// \brief Dumps deserialized declarations. 33b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidisclass DeserializedDeclsDumper : public ASTDeserializationListener { 34b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis ASTDeserializationListener *Previous; 35b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 36b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidispublic: 37b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis DeserializedDeclsDumper(ASTDeserializationListener *Previous) 38b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis : Previous(Previous) { } 39b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 40b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis virtual void DeclRead(serialization::DeclID ID, const Decl *D) { 41b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis llvm::outs() << "PCH DECL: " << D->getDeclKindName(); 42b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 43b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis llvm::outs() << " - " << ND->getNameAsString(); 44b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis llvm::outs() << "\n"; 45b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 46b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis if (Previous) 47b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis Previous->DeclRead(ID, D); 48b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis } 49b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis}; 50b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 513e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis /// \brief Checks deserialized declarations and emits error if a name 523e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis /// matches one given in command-line using -error-on-deserialized-decl. 533e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis class DeserializedDeclsChecker : public ASTDeserializationListener { 543e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis ASTContext &Ctx; 553e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis std::set<std::string> NamesToCheck; 563e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis ASTDeserializationListener *Previous; 573e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis 583e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis public: 593e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis DeserializedDeclsChecker(ASTContext &Ctx, 603e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis const std::set<std::string> &NamesToCheck, 613e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis ASTDeserializationListener *Previous) 623e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis : Ctx(Ctx), NamesToCheck(NamesToCheck), Previous(Previous) { } 633e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis 643e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis virtual void DeclRead(serialization::DeclID ID, const Decl *D) { 653e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 663e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) { 673e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis unsigned DiagID 683e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis = Ctx.getDiagnostics().getCustomDiagID(Diagnostic::Error, 693e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis "%0 was deserialized"); 703e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID) 713e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis << ND->getNameAsString(); 723e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis } 733e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis 743e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis if (Previous) 753e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis Previous->DeclRead(ID, D); 763e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis } 773e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis}; 783e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis 79b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis} // end anonymous namespace 80b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis 81f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan RajaratnamFrontendAction::FrontendAction() : Instance(0) {} 824ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 834ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel DunbarFrontendAction::~FrontendAction() {} 844ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 85685ac6665a3f91f9a66a9f44b6bf755a0cd929eaDaniel Dunbarvoid FrontendAction::setCurrentFile(llvm::StringRef Value, InputKind Kind, 86685ac6665a3f91f9a66a9f44b6bf755a0cd929eaDaniel Dunbar ASTUnit *AST) { 874ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CurrentFile = Value; 88685ac6665a3f91f9a66a9f44b6bf755a0cd929eaDaniel Dunbar CurrentFileKind = Kind; 894ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CurrentASTUnit.reset(AST); 904ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 914ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 925aa74affa5d61d04c4b034b3722ca41aec0cba6eNico WeberASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, 935aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber llvm::StringRef InFile) { 945aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber ASTConsumer* Consumer = CreateASTConsumer(CI, InFile); 955aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber if (!Consumer) 965aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber return 0; 975aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber 985aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber if (CI.getFrontendOpts().AddPluginActions.size() == 0) 995aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber return Consumer; 1005aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber 1015aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber // Make sure the non-plugin consumer is first, so that plugins can't 1025aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber // modifiy the AST. 1035aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber std::vector<ASTConsumer*> Consumers(1, Consumer); 1045aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber 1055aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size(); 1065aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber i != e; ++i) { 1075aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber // This is O(|plugins| * |add_plugins|), but since both numbers are 1085aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber // way below 50 in practice, that's ok. 1095aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber for (FrontendPluginRegistry::iterator 1105aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber it = FrontendPluginRegistry::begin(), 1115aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber ie = FrontendPluginRegistry::end(); 1125aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber it != ie; ++it) { 1135aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) { 1145aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber llvm::OwningPtr<PluginASTAction> P(it->instantiate()); 1155aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber FrontendAction* c = P.get(); 116f25649c74397d2620e6ac61f1045261644707c80Nico Weber if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i])) 1175aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber Consumers.push_back(c->CreateASTConsumer(CI, InFile)); 1185aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber } 1195aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber } 1205aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber } 1215aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber 1225aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber return new MultiplexConsumer(Consumers); 1235aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber} 1245aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber 1254ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbarbool FrontendAction::BeginSourceFile(CompilerInstance &CI, 1264ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar llvm::StringRef Filename, 127d3598a65716e120aef45aa2841d730e03f7101feDaniel Dunbar InputKind InputKind) { 1284ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar assert(!Instance && "Already processing a source file!"); 1294ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar assert(!Filename.empty() && "Unexpected empty filename!"); 130685ac6665a3f91f9a66a9f44b6bf755a0cd929eaDaniel Dunbar setCurrentFile(Filename, InputKind); 1314ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar setCompilerInstance(&CI); 1324ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 1334ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // AST files follow a very different path, since they share objects via the 1344ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // AST unit. 1352056048f0f619adadc9a5416a2c4cdf95c58eef7Daniel Dunbar if (InputKind == IK_AST) { 1364ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar assert(!usesPreprocessorOnly() && 1374ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar "Attempt to pass AST file to preprocessor only action!"); 138eb58d831b283a9fa030a2eccc6e23480108d2fa1Daniel Dunbar assert(hasASTFileSupport() && 139eb58d831b283a9fa030a2eccc6e23480108d2fa1Daniel Dunbar "This action does not have AST file support!"); 1404ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 14128019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics()); 1424ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar std::string Error; 143389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis ASTUnit *AST = ASTUnit::LoadFromASTFile(Filename, Diags, 144389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis CI.getFileSystemOpts()); 1455262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar if (!AST) 1464ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar goto failure; 1474ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 148685ac6665a3f91f9a66a9f44b6bf755a0cd929eaDaniel Dunbar setCurrentFile(Filename, InputKind, AST); 1494ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 1504ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Set the shared objects, these are reset when we finish processing the 1514ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // file, otherwise the CompilerInstance will happily destroy them. 1524ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.setFileManager(&AST->getFileManager()); 1534ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.setSourceManager(&AST->getSourceManager()); 1544ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.setPreprocessor(&AST->getPreprocessor()); 1554ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.setASTContext(&AST->getASTContext()); 1564ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 1574ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Initialize the action. 1584ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (!BeginSourceFileAction(CI, Filename)) 1594ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar goto failure; 1604ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 1614ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar /// Create the AST consumer. 1625aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber CI.setASTConsumer(CreateWrappedASTConsumer(CI, Filename)); 1634ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (!CI.hasASTConsumer()) 1644ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar goto failure; 1654ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 1664ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar return true; 1674ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 1684ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 169faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar // Set up the file and source managers, if needed. 1702056048f0f619adadc9a5416a2c4cdf95c58eef7Daniel Dunbar if (!CI.hasFileManager()) 1712056048f0f619adadc9a5416a2c4cdf95c58eef7Daniel Dunbar CI.createFileManager(); 1722056048f0f619adadc9a5416a2c4cdf95c58eef7Daniel Dunbar if (!CI.hasSourceManager()) 17339b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner CI.createSourceManager(CI.getFileManager()); 174faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar 175faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar // IR files bypass the rest of initialization. 176faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar if (InputKind == IK_LLVM_IR) { 177faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar assert(hasIRSupport() && 178faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar "This action does not have IR file support!"); 179faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar 180faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar // Inform the diagnostic client we are processing a source file. 181faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0); 182faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar 183faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar // Initialize the action. 184faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar if (!BeginSourceFileAction(CI, Filename)) 185faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar goto failure; 186faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar 187faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar return true; 188faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar } 189faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar 190faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar // Set up the preprocessor. 1912056048f0f619adadc9a5416a2c4cdf95c58eef7Daniel Dunbar CI.createPreprocessor(); 1922056048f0f619adadc9a5416a2c4cdf95c58eef7Daniel Dunbar 1934ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Inform the diagnostic client we are processing a source file. 1944ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 1954ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar &CI.getPreprocessor()); 1964ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 1974ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Initialize the action. 1984ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (!BeginSourceFileAction(CI, Filename)) 1994ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar goto failure; 2004ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2014ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar /// Create the AST context and consumer unless this is a preprocessor only 2024ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar /// action. 2034ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (!usesPreprocessorOnly()) { 2044ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.createASTContext(); 2054ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2065aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber llvm::OwningPtr<ASTConsumer> Consumer( 2075aa74affa5d61d04c4b034b3722ca41aec0cba6eNico Weber CreateWrappedASTConsumer(CI, Filename)); 208d305719f9b7e154a822ff6688c663cbd32bb1d7bFariborz Jahanian if (!Consumer) 209d305719f9b7e154a822ff6688c663cbd32bb1d7bFariborz Jahanian goto failure; 210ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl 2117b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); 2127b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis 213b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { 214b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis // Convert headers to PCH and chain them. 215b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis llvm::OwningPtr<ExternalASTSource> source; 216b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis source.reset(ChainedIncludesSource::create(CI)); 217b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis if (!source) 218b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis goto failure; 219b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis CI.getASTContext().setExternalSource(source); 220b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis 221b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { 222b0f4b9a558933b307073f7cd7753602f94354ae9Argyrios Kyrtzidis // Use PCH. 2234ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar assert(hasPCHSupport() && "This action does not have PCH support!"); 224b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis ASTDeserializationListener *DeserialListener 225b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis = CI.getInvocation().getFrontendOpts().ChainedPCH ? 226b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis Consumer->GetASTDeserializationListener() : 0; 227b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) 228b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis DeserialListener = new DeserializedDeclsDumper(DeserialListener); 2293e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) 2303e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(), 2313e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn, 2323e78593b1ced32b7e0a97da044213014ee0f6f7cArgyrios Kyrtzidis DeserialListener); 2334ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.createPCHExternalASTSource( 234fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor CI.getPreprocessorOpts().ImplicitPCHInclude, 235ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl CI.getPreprocessorOpts().DisablePCHValidation, 2368ef6c8cb6c5627240e2339fd7062c9873f821d7eDouglas Gregor CI.getPreprocessorOpts().DisableStatCache, 237b972858068d2ea77f72a1e7b1812b196afd6be2eArgyrios Kyrtzidis DeserialListener); 2384ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (!CI.getASTContext().getExternalSource()) 2394ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar goto failure; 2404ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 24177f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl 242ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl CI.setASTConsumer(Consumer.take()); 24377f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl if (!CI.hasASTConsumer()) 24477f4603c8b142e642300959a601ecec2b7c8e288Sebastian Redl goto failure; 2454ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 2464ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2474ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Initialize builtin info as long as we aren't using an external AST 2484ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // source. 2494ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { 2504ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar Preprocessor &PP = CI.getPreprocessor(); 2514ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), 25267aba816901503d9cf7ba699525fa62cc7f8e5e4Fariborz Jahanian PP.getLangOptions()); 2534ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 2544ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2554ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar return true; 2564ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2574ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // If we failed, reset state since the client will not end up calling the 2584ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // matching EndSourceFile(). 2594ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar failure: 2604ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (isCurrentFileAST()) { 2614ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.takeASTContext(); 2624ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.takePreprocessor(); 2634ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.takeSourceManager(); 2644ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.takeFileManager(); 2654ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 2664ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2674ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getDiagnosticClient().EndSourceFile(); 268685ac6665a3f91f9a66a9f44b6bf755a0cd929eaDaniel Dunbar setCurrentFile("", IK_None); 2694ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar setCompilerInstance(0); 2704ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar return false; 2714ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 2724ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2734ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbarvoid FrontendAction::Execute() { 2744ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CompilerInstance &CI = getCompilerInstance(); 2754ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2764ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Initialize the main file entry. This needs to be delayed until after PCH 2774ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // has loaded. 2784ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (isCurrentFileAST()) { 2794ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Set the main file ID to an empty file. 2804ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // 2814ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // FIXME: We probably shouldn't need this, but for now this is the 2824ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // simplest way to reuse the logic in ParseAST. 2834ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar const char *EmptyStr = ""; 2844ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar llvm::MemoryBuffer *SB = 285a0a270c0f1c0a4e3482438bdc5f4a7bd3d25f0a6Chris Lattner llvm::MemoryBuffer::getMemBuffer(EmptyStr, "<dummy input>"); 2864ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getSourceManager().createMainFileIDForMemBuffer(SB); 2874ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } else { 2884ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (!CI.InitializeSourceManager(getCurrentFile())) 2894ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar return; 2904ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 2914ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 292f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan Rajaratnam if (CI.hasFrontendTimer()) { 293f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan Rajaratnam llvm::TimeRegion Timer(CI.getFrontendTimer()); 294f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan Rajaratnam ExecuteAction(); 295f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan Rajaratnam } 296f79bafa608a5d7c49ec40ad199af5e32f3038b47Kovarththanan Rajaratnam else ExecuteAction(); 2974ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 2984ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 2994ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbarvoid FrontendAction::EndSourceFile() { 3004ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CompilerInstance &CI = getCompilerInstance(); 3014ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 30292b97f2d279405751447488504816d82e1906f4fDouglas Gregor // Inform the diagnostic client we are done with this source file. 30392b97f2d279405751447488504816d82e1906f4fDouglas Gregor CI.getDiagnosticClient().EndSourceFile(); 30492b97f2d279405751447488504816d82e1906f4fDouglas Gregor 3054ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Finalize the action. 3064ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar EndSourceFileAction(); 3074ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3084ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Release the consumer and the AST, in that order since the consumer may 3094ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // perform actions in its destructor which require the context. 3104ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // 3114ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // FIXME: There is more per-file stuff we could just drop here? 3124ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (CI.getFrontendOpts().DisableFree) { 3134ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.takeASTConsumer(); 314f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor if (!isCurrentFileAST()) { 315f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor CI.takeSema(); 3164ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.takeASTContext(); 317f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor } 3184ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } else { 319f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor if (!isCurrentFileAST()) { 320f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor CI.setSema(0); 3214ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.setASTContext(0); 322f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor } 323f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor CI.setASTConsumer(0); 3244ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 3254ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 326dbd8209b33e6c9f151e4913a9c095d64a95439c4Daniel Dunbar // Inform the preprocessor we are done. 327dbd8209b33e6c9f151e4913a9c095d64a95439c4Daniel Dunbar if (CI.hasPreprocessor()) 328dbd8209b33e6c9f151e4913a9c095d64a95439c4Daniel Dunbar CI.getPreprocessor().EndSourceFile(); 329dbd8209b33e6c9f151e4913a9c095d64a95439c4Daniel Dunbar 3304ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (CI.getFrontendOpts().ShowStats) { 3314ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n"; 3324ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getPreprocessor().PrintStats(); 3334ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getPreprocessor().getIdentifierTable().PrintStats(); 3344ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getPreprocessor().getHeaderSearchInfo().PrintStats(); 3354ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.getSourceManager().PrintStats(); 3364ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar llvm::errs() << "\n"; 3374ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 3384ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3394ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Cleanup the output streams, and erase the output files if we encountered 3404ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // an error. 341be3aab6abe5e66bb86596da806acc49614eacb69Argyrios Kyrtzidis CI.clearOutputFiles(/*EraseFiles=*/CI.getDiagnostics().hasErrorOccurred()); 3424ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3434ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (isCurrentFileAST()) { 344f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor CI.takeSema(); 3454ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.takeASTContext(); 3464ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.takePreprocessor(); 3474ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.takeSourceManager(); 3484ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.takeFileManager(); 3494ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar } 3504ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3514ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar setCompilerInstance(0); 352685ac6665a3f91f9a66a9f44b6bf755a0cd929eaDaniel Dunbar setCurrentFile("", IK_None); 3534ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 3544ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3554ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar//===----------------------------------------------------------------------===// 3564ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar// Utility Actions 3574ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar//===----------------------------------------------------------------------===// 3584ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3594ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbarvoid ASTFrontendAction::ExecuteAction() { 3604ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CompilerInstance &CI = getCompilerInstance(); 3614ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3624ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // FIXME: Move the truncation aspect of this into Sema, we delayed this till 3634ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // here so the source manager would be initialized. 3644ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (hasCodeCompletionSupport() && 3654ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar !CI.getFrontendOpts().CodeCompletionAt.FileName.empty()) 3664ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CI.createCodeCompletionConsumer(); 3674ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3684ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar // Use a code completion consumer? 3694ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CodeCompleteConsumer *CompletionConsumer = 0; 3704ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar if (CI.hasCodeCompletionConsumer()) 3714ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar CompletionConsumer = &CI.getCodeCompletionConsumer(); 3724ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 373f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor if (!CI.hasSema()) 374f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor CI.createSema(usesCompleteTranslationUnit(), CompletionConsumer); 375f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor 376f18d0d8b39e891460d50f8a8b85029885b264986Douglas Gregor ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats); 3774ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 3784ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar 3794ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel DunbarASTConsumer * 3804ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel DunbarPreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI, 3814ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar llvm::StringRef InFile) { 3829f61aa9e280adea9fbf3365f0e4f6ed568c9885aJeffrey Yasskin llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!"); 3834ee24097a8050b885c1d75ca4ee9f6d534c3f20bDaniel Dunbar} 384