1636404a3SDaniel Dunbar //===--- CompilerInstance.cpp ---------------------------------------------===//
2636404a3SDaniel Dunbar //
3636404a3SDaniel Dunbar //                     The LLVM Compiler Infrastructure
4636404a3SDaniel Dunbar //
5636404a3SDaniel Dunbar // This file is distributed under the University of Illinois Open Source
6636404a3SDaniel Dunbar // License. See LICENSE.TXT for details.
7636404a3SDaniel Dunbar //
8636404a3SDaniel Dunbar //===----------------------------------------------------------------------===//
9636404a3SDaniel Dunbar 
10636404a3SDaniel Dunbar #include "clang/Frontend/CompilerInstance.h"
1156d9c293SDaniel Dunbar #include "clang/AST/ASTConsumer.h"
12df3e30c4SDaniel Dunbar #include "clang/AST/ASTContext.h"
13bcfc7d02SDouglas Gregor #include "clang/AST/Decl.h"
14636404a3SDaniel Dunbar #include "clang/Basic/Diagnostic.h"
15546a676aSDaniel Dunbar #include "clang/Basic/FileManager.h"
16546a676aSDaniel Dunbar #include "clang/Basic/SourceManager.h"
17636404a3SDaniel Dunbar #include "clang/Basic/TargetInfo.h"
184f2bc55dSDaniel Dunbar #include "clang/Basic/Version.h"
198b00dcb0SDavid Blaikie #include "clang/Frontend/ChainedDiagnosticConsumer.h"
204f2bc55dSDaniel Dunbar #include "clang/Frontend/FrontendAction.h"
21faeb1d46SDouglas Gregor #include "clang/Frontend/FrontendActions.h"
22f7093b5aSDaniel Dunbar #include "clang/Frontend/FrontendDiagnostic.h"
232083c32fSDaniel Dunbar #include "clang/Frontend/LogDiagnosticPrinter.h"
244610ea2bSTed Kremenek #include "clang/Frontend/SerializedDiagnosticPrinter.h"
257d75afc5SDaniel Dunbar #include "clang/Frontend/TextDiagnosticPrinter.h"
26aaa148fdSDaniel Dunbar #include "clang/Frontend/Utils.h"
273a02247dSChandler Carruth #include "clang/Frontend/VerifyDiagnosticConsumer.h"
283a02247dSChandler Carruth #include "clang/Lex/HeaderSearch.h"
293a02247dSChandler Carruth #include "clang/Lex/PTHManager.h"
303a02247dSChandler Carruth #include "clang/Lex/Preprocessor.h"
31f7093b5aSDaniel Dunbar #include "clang/Sema/CodeCompleteConsumer.h"
323a02247dSChandler Carruth #include "clang/Sema/Sema.h"
333a02247dSChandler Carruth #include "clang/Serialization/ASTReader.h"
34171b780cSDouglas Gregor #include "llvm/ADT/Statistic.h"
353a02247dSChandler Carruth #include "llvm/Config/config.h"
363a02247dSChandler Carruth #include "llvm/Support/CrashRecoveryContext.h"
373a02247dSChandler Carruth #include "llvm/Support/FileSystem.h"
388aaf4995SMichael J. Spencer #include "llvm/Support/Host.h"
39e212489fSDouglas Gregor #include "llvm/Support/LockFileManager.h"
403a02247dSChandler Carruth #include "llvm/Support/MemoryBuffer.h"
418aaf4995SMichael J. Spencer #include "llvm/Support/Path.h"
428aaf4995SMichael J. Spencer #include "llvm/Support/Program.h"
438aaf4995SMichael J. Spencer #include "llvm/Support/Signals.h"
443a02247dSChandler Carruth #include "llvm/Support/Timer.h"
453a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h"
46f25faaafSMichael J. Spencer #include "llvm/Support/system_error.h"
4754a88810SDouglas Gregor 
48636404a3SDaniel Dunbar using namespace clang;
49636404a3SDaniel Dunbar 
50e922d9bdSDaniel Dunbar CompilerInstance::CompilerInstance()
51925296b4SDouglas Gregor   : Invocation(new CompilerInvocation()), ModuleManager(0) {
52636404a3SDaniel Dunbar }
53636404a3SDaniel Dunbar 
54636404a3SDaniel Dunbar CompilerInstance::~CompilerInstance() {
553c717b45SBenjamin Kramer   assert(OutputFiles.empty() && "Still output files in flight?");
56e922d9bdSDaniel Dunbar }
57e922d9bdSDaniel Dunbar 
5868242254SDaniel Dunbar void CompilerInstance::setInvocation(CompilerInvocation *Value) {
595e14d39aSTed Kremenek   Invocation = Value;
6068242254SDaniel Dunbar }
6168242254SDaniel Dunbar 
629c902b55SDavid Blaikie void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) {
637f95d26eSDouglas Gregor   Diagnostics = Value;
64e01dc86dSDaniel Dunbar }
65e01dc86dSDaniel Dunbar 
66e01dc86dSDaniel Dunbar void CompilerInstance::setTarget(TargetInfo *Value) {
675e14d39aSTed Kremenek   Target = Value;
68e01dc86dSDaniel Dunbar }
69e01dc86dSDaniel Dunbar 
70e01dc86dSDaniel Dunbar void CompilerInstance::setFileManager(FileManager *Value) {
715e14d39aSTed Kremenek   FileMgr = Value;
72e01dc86dSDaniel Dunbar }
73e01dc86dSDaniel Dunbar 
74e01dc86dSDaniel Dunbar void CompilerInstance::setSourceManager(SourceManager *Value) {
755e14d39aSTed Kremenek   SourceMgr = Value;
76e01dc86dSDaniel Dunbar }
77e01dc86dSDaniel Dunbar 
785e14d39aSTed Kremenek void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; }
79e01dc86dSDaniel Dunbar 
805e14d39aSTed Kremenek void CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; }
81e01dc86dSDaniel Dunbar 
820e93f017SDouglas Gregor void CompilerInstance::setSema(Sema *S) {
830e93f017SDouglas Gregor   TheSema.reset(S);
840e93f017SDouglas Gregor }
850e93f017SDouglas Gregor 
8656d9c293SDaniel Dunbar void CompilerInstance::setASTConsumer(ASTConsumer *Value) {
8756d9c293SDaniel Dunbar   Consumer.reset(Value);
8856d9c293SDaniel Dunbar }
8956d9c293SDaniel Dunbar 
90e01dc86dSDaniel Dunbar void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
91e01dc86dSDaniel Dunbar   CompletionConsumer.reset(Value);
92e01dc86dSDaniel Dunbar }
93e01dc86dSDaniel Dunbar 
947d75afc5SDaniel Dunbar // Diagnostics
95811db4eaSDouglas Gregor static void SetUpBuildDumpLog(DiagnosticOptions *DiagOpts,
9689c31490SAxel Naumann                               unsigned argc, const char* const *argv,
979c902b55SDavid Blaikie                               DiagnosticsEngine &Diags) {
987d75afc5SDaniel Dunbar   std::string ErrorInfo;
99e2778999SDylan Noblesmith   OwningPtr<raw_ostream> OS(
100811db4eaSDouglas Gregor     new llvm::raw_fd_ostream(DiagOpts->DumpBuildInformation.c_str(),ErrorInfo));
1017d75afc5SDaniel Dunbar   if (!ErrorInfo.empty()) {
1024a94ba56SKovarththanan Rajaratnam     Diags.Report(diag::err_fe_unable_to_open_logfile)
103811db4eaSDouglas Gregor                  << DiagOpts->DumpBuildInformation << ErrorInfo;
1047d75afc5SDaniel Dunbar     return;
1057d75afc5SDaniel Dunbar   }
1067d75afc5SDaniel Dunbar 
107520d1e6cSDaniel Dunbar   (*OS) << "clang -cc1 command line arguments: ";
1087d75afc5SDaniel Dunbar   for (unsigned i = 0; i != argc; ++i)
1097d75afc5SDaniel Dunbar     (*OS) << argv[i] << ' ';
1107d75afc5SDaniel Dunbar   (*OS) << '\n';
1117d75afc5SDaniel Dunbar 
1127d75afc5SDaniel Dunbar   // Chain in a diagnostic client which will log the diagnostics.
113e2eefaecSDavid Blaikie   DiagnosticConsumer *Logger =
114eeed0cc3SKovarththanan Rajaratnam     new TextDiagnosticPrinter(*OS.take(), DiagOpts, /*OwnsOutputStream=*/true);
1158b00dcb0SDavid Blaikie   Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger));
1167d75afc5SDaniel Dunbar }
1177d75afc5SDaniel Dunbar 
118811db4eaSDouglas Gregor static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
1197b83306dSDaniel Dunbar                                const CodeGenOptions *CodeGenOpts,
1209c902b55SDavid Blaikie                                DiagnosticsEngine &Diags) {
1212083c32fSDaniel Dunbar   std::string ErrorInfo;
1222083c32fSDaniel Dunbar   bool OwnsStream = false;
1230e62c1ccSChris Lattner   raw_ostream *OS = &llvm::errs();
124811db4eaSDouglas Gregor   if (DiagOpts->DiagnosticLogFile != "-") {
1252083c32fSDaniel Dunbar     // Create the output stream.
1262083c32fSDaniel Dunbar     llvm::raw_fd_ostream *FileOS(
127811db4eaSDouglas Gregor       new llvm::raw_fd_ostream(DiagOpts->DiagnosticLogFile.c_str(),
12844d9ef78SDaniel Dunbar                                ErrorInfo, llvm::raw_fd_ostream::F_Append));
1292083c32fSDaniel Dunbar     if (!ErrorInfo.empty()) {
1302083c32fSDaniel Dunbar       Diags.Report(diag::warn_fe_cc_log_diagnostics_failure)
131811db4eaSDouglas Gregor         << DiagOpts->DumpBuildInformation << ErrorInfo;
1322083c32fSDaniel Dunbar     } else {
1332083c32fSDaniel Dunbar       FileOS->SetUnbuffered();
1342083c32fSDaniel Dunbar       FileOS->SetUseAtomicWrites(true);
1352083c32fSDaniel Dunbar       OS = FileOS;
1362083c32fSDaniel Dunbar       OwnsStream = true;
1372083c32fSDaniel Dunbar     }
1382083c32fSDaniel Dunbar   }
1392083c32fSDaniel Dunbar 
1402083c32fSDaniel Dunbar   // Chain in the diagnostic client which will log the diagnostics.
1417b83306dSDaniel Dunbar   LogDiagnosticPrinter *Logger = new LogDiagnosticPrinter(*OS, DiagOpts,
1422083c32fSDaniel Dunbar                                                           OwnsStream);
1437b83306dSDaniel Dunbar   if (CodeGenOpts)
1447b83306dSDaniel Dunbar     Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags);
1458b00dcb0SDavid Blaikie   Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger));
1462083c32fSDaniel Dunbar }
1472083c32fSDaniel Dunbar 
148811db4eaSDouglas Gregor static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts,
1494610ea2bSTed Kremenek                                        DiagnosticsEngine &Diags,
1504610ea2bSTed Kremenek                                        StringRef OutputFile) {
1514610ea2bSTed Kremenek   std::string ErrorInfo;
152e2778999SDylan Noblesmith   OwningPtr<llvm::raw_fd_ostream> OS;
1534610ea2bSTed Kremenek   OS.reset(new llvm::raw_fd_ostream(OutputFile.str().c_str(), ErrorInfo,
1544610ea2bSTed Kremenek                                     llvm::raw_fd_ostream::F_Binary));
1554610ea2bSTed Kremenek 
1564610ea2bSTed Kremenek   if (!ErrorInfo.empty()) {
1574610ea2bSTed Kremenek     Diags.Report(diag::warn_fe_serialized_diag_failure)
1584610ea2bSTed Kremenek       << OutputFile << ErrorInfo;
1594610ea2bSTed Kremenek     return;
1604610ea2bSTed Kremenek   }
1614610ea2bSTed Kremenek 
1624610ea2bSTed Kremenek   DiagnosticConsumer *SerializedConsumer =
1634548e044STed Kremenek     clang::serialized_diags::create(OS.take(), DiagOpts);
1644610ea2bSTed Kremenek 
1654610ea2bSTed Kremenek 
1664610ea2bSTed Kremenek   Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(),
1674610ea2bSTed Kremenek                                                 SerializedConsumer));
1684610ea2bSTed Kremenek }
1694610ea2bSTed Kremenek 
17044c6ee77SDouglas Gregor void CompilerInstance::createDiagnostics(int Argc, const char* const *Argv,
171e2eefaecSDavid Blaikie                                          DiagnosticConsumer *Client,
172d0e9e3a6SDouglas Gregor                                          bool ShouldOwnClient,
173d0e9e3a6SDouglas Gregor                                          bool ShouldCloneClient) {
174811db4eaSDouglas Gregor   Diagnostics = createDiagnostics(&getDiagnosticOpts(), Argc, Argv, Client,
175d0e9e3a6SDouglas Gregor                                   ShouldOwnClient, ShouldCloneClient,
176d0e9e3a6SDouglas Gregor                                   &getCodeGenOpts());
1777d75afc5SDaniel Dunbar }
1787d75afc5SDaniel Dunbar 
179c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine>
180811db4eaSDouglas Gregor CompilerInstance::createDiagnostics(DiagnosticOptions *Opts,
18144c6ee77SDouglas Gregor                                     int Argc, const char* const *Argv,
182e2eefaecSDavid Blaikie                                     DiagnosticConsumer *Client,
1832b9b4642SDouglas Gregor                                     bool ShouldOwnClient,
184d0e9e3a6SDouglas Gregor                                     bool ShouldCloneClient,
1857b83306dSDaniel Dunbar                                     const CodeGenOptions *CodeGenOpts) {
186c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
187c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticsEngine>
188811db4eaSDouglas Gregor       Diags(new DiagnosticsEngine(DiagID, Opts));
1891b39a2edSDaniel Dunbar 
1907d75afc5SDaniel Dunbar   // Create the diagnostic client for reporting errors or for
1917d75afc5SDaniel Dunbar   // implementing -verify.
192d0e9e3a6SDouglas Gregor   if (Client) {
193d0e9e3a6SDouglas Gregor     if (ShouldCloneClient)
194d0e9e3a6SDouglas Gregor       Diags->setClient(Client->clone(*Diags), ShouldOwnClient);
19544c6ee77SDouglas Gregor     else
196d0e9e3a6SDouglas Gregor       Diags->setClient(Client, ShouldOwnClient);
197d0e9e3a6SDouglas Gregor   } else
1982dd19f1dSDouglas Gregor     Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));
19950ec0da0SDaniel Dunbar 
20050ec0da0SDaniel Dunbar   // Chain in -verify checker, if requested.
201811db4eaSDouglas Gregor   if (Opts->VerifyDiagnostics)
20269609dceSDavid Blaikie     Diags->setClient(new VerifyDiagnosticConsumer(*Diags));
2037d75afc5SDaniel Dunbar 
2042083c32fSDaniel Dunbar   // Chain in -diagnostic-log-file dumper, if requested.
205811db4eaSDouglas Gregor   if (!Opts->DiagnosticLogFile.empty())
2067b83306dSDaniel Dunbar     SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags);
2072083c32fSDaniel Dunbar 
208811db4eaSDouglas Gregor   if (!Opts->DumpBuildInformation.empty())
2094a94ba56SKovarththanan Rajaratnam     SetUpBuildDumpLog(Opts, Argc, Argv, *Diags);
2107d75afc5SDaniel Dunbar 
211811db4eaSDouglas Gregor   if (!Opts->DiagnosticSerializationFile.empty())
2124610ea2bSTed Kremenek     SetupSerializedDiagnostics(Opts, *Diags,
213811db4eaSDouglas Gregor                                Opts->DiagnosticSerializationFile);
2144610ea2bSTed Kremenek 
2157d75afc5SDaniel Dunbar   // Configure our handling of diagnostics.
216811db4eaSDouglas Gregor   ProcessWarningOptions(*Diags, *Opts);
2177d75afc5SDaniel Dunbar 
2187f95d26eSDouglas Gregor   return Diags;
2197d75afc5SDaniel Dunbar }
2207d75afc5SDaniel Dunbar 
2217d75afc5SDaniel Dunbar // File Manager
2227d75afc5SDaniel Dunbar 
223546a676aSDaniel Dunbar void CompilerInstance::createFileManager() {
2245e14d39aSTed Kremenek   FileMgr = new FileManager(getFileSystemOpts());
225546a676aSDaniel Dunbar }
226546a676aSDaniel Dunbar 
2277d75afc5SDaniel Dunbar // Source Manager
2287d75afc5SDaniel Dunbar 
2295159f616SChris Lattner void CompilerInstance::createSourceManager(FileManager &FileMgr) {
2305e14d39aSTed Kremenek   SourceMgr = new SourceManager(getDiagnostics(), FileMgr);
231546a676aSDaniel Dunbar }
232aaa148fdSDaniel Dunbar 
2337d75afc5SDaniel Dunbar // Preprocessor
2347d75afc5SDaniel Dunbar 
235aaa148fdSDaniel Dunbar void CompilerInstance::createPreprocessor() {
23608142534SDouglas Gregor   const PreprocessorOptions &PPOpts = getPreprocessorOpts();
237aaa148fdSDaniel Dunbar 
238aaa148fdSDaniel Dunbar   // Create a PTH manager if we are using some form of a token cache.
239aaa148fdSDaniel Dunbar   PTHManager *PTHMgr = 0;
240d6ea9028SDaniel Dunbar   if (!PPOpts.TokenCache.empty())
24108142534SDouglas Gregor     PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics());
242aaa148fdSDaniel Dunbar 
243aaa148fdSDaniel Dunbar   // Create the Preprocessor.
244b85b9ccbSDouglas Gregor   HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(),
245b85b9ccbSDouglas Gregor                                               getFileManager(),
2461fb5c3a6SDouglas Gregor                                               getDiagnostics(),
24789929282SDouglas Gregor                                               getLangOpts(),
24889929282SDouglas Gregor                                               &getTarget());
2491452ff15SDouglas Gregor   PP = new Preprocessor(&getPreprocessorOpts(),
2501452ff15SDouglas Gregor                         getDiagnostics(), getLangOpts(), &getTarget(),
25108142534SDouglas Gregor                         getSourceManager(), *HeaderInfo, *this, PTHMgr,
252aaa148fdSDaniel Dunbar                         /*OwnsHeaderSearch=*/true);
253aaa148fdSDaniel Dunbar 
254aaa148fdSDaniel Dunbar   // Note that this is different then passing PTHMgr to Preprocessor's ctor.
255aaa148fdSDaniel Dunbar   // That argument is used as the IdentifierInfoLookup argument to
256aaa148fdSDaniel Dunbar   // IdentifierTable's ctor.
257aaa148fdSDaniel Dunbar   if (PTHMgr) {
25808142534SDouglas Gregor     PTHMgr->setPreprocessor(&*PP);
259aaa148fdSDaniel Dunbar     PP->setPTHManager(PTHMgr);
260aaa148fdSDaniel Dunbar   }
261aaa148fdSDaniel Dunbar 
2627f6d60dcSDouglas Gregor   if (PPOpts.DetailedRecord)
263f3d587eaSArgyrios Kyrtzidis     PP->createPreprocessingRecord();
2647f6d60dcSDouglas Gregor 
26508142534SDouglas Gregor   InitializePreprocessor(*PP, PPOpts, getHeaderSearchOpts(), getFrontendOpts());
266aaa148fdSDaniel Dunbar 
2671735f4e7SDouglas Gregor   // Set up the module path, including the hash for the
2681735f4e7SDouglas Gregor   // module-creation options.
2692c1dd271SDylan Noblesmith   SmallString<256> SpecificModuleCache(
2701735f4e7SDouglas Gregor                            getHeaderSearchOpts().ModuleCachePath);
2711735f4e7SDouglas Gregor   if (!getHeaderSearchOpts().DisableModuleHash)
2721735f4e7SDouglas Gregor     llvm::sys::path::append(SpecificModuleCache,
2731735f4e7SDouglas Gregor                             getInvocation().getModuleHash());
2742537a364SDouglas Gregor   PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache);
2751735f4e7SDouglas Gregor 
276aaa148fdSDaniel Dunbar   // Handle generating dependencies, if requested.
27708142534SDouglas Gregor   const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
278aaa148fdSDaniel Dunbar   if (!DepOpts.OutputFile.empty())
279aaa148fdSDaniel Dunbar     AttachDependencyFileGen(*PP, DepOpts);
2802e129659SDouglas Gregor   if (!DepOpts.DOTOutputFile.empty())
2812e129659SDouglas Gregor     AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,
28283d46be3SDouglas Gregor                              getHeaderSearchOpts().Sysroot);
28383d46be3SDouglas Gregor 
284aaa148fdSDaniel Dunbar 
28527734fdbSDaniel Dunbar   // Handle generating header include information, if requested.
28627734fdbSDaniel Dunbar   if (DepOpts.ShowHeaderIncludes)
28727734fdbSDaniel Dunbar     AttachHeaderIncludeGen(*PP);
2881af1d275SDaniel Dunbar   if (!DepOpts.HeaderIncludeOutputFile.empty()) {
2890e62c1ccSChris Lattner     StringRef OutputPath = DepOpts.HeaderIncludeOutputFile;
2901af1d275SDaniel Dunbar     if (OutputPath == "-")
2911af1d275SDaniel Dunbar       OutputPath = "";
292fe908a80SDaniel Dunbar     AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath,
293fe908a80SDaniel Dunbar                            /*ShowDepth=*/false);
2941af1d275SDaniel Dunbar   }
295aaa148fdSDaniel Dunbar }
296df3e30c4SDaniel Dunbar 
297df3e30c4SDaniel Dunbar // ASTContext
298df3e30c4SDaniel Dunbar 
299df3e30c4SDaniel Dunbar void CompilerInstance::createASTContext() {
300df3e30c4SDaniel Dunbar   Preprocessor &PP = getPreprocessor();
3015e14d39aSTed Kremenek   Context = new ASTContext(getLangOpts(), PP.getSourceManager(),
302e8bbc121SDouglas Gregor                            &getTarget(), PP.getIdentifierTable(),
303df3e30c4SDaniel Dunbar                            PP.getSelectorTable(), PP.getBuiltinInfo(),
3045e14d39aSTed Kremenek                            /*size_reserve=*/ 0);
305df3e30c4SDaniel Dunbar }
306599313efSDaniel Dunbar 
307599313efSDaniel Dunbar // ExternalASTSource
308599313efSDaniel Dunbar 
3090e62c1ccSChris Lattner void CompilerInstance::createPCHExternalASTSource(StringRef Path,
31007a89a83SSebastian Redl                                                   bool DisablePCHValidation,
3114a280ff4SArgyrios Kyrtzidis                                                 bool AllowPCHWithCompilerErrors,
31207a89a83SSebastian Redl                                                  void *DeserializationListener){
313e2778999SDylan Noblesmith   OwningPtr<ExternalASTSource> Source;
314009e7f20SSebastian Redl   bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
315599313efSDaniel Dunbar   Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot,
316ce3a8293SDouglas Gregor                                           DisablePCHValidation,
3174a280ff4SArgyrios Kyrtzidis                                           AllowPCHWithCompilerErrors,
31807a89a83SSebastian Redl                                           getPreprocessor(), getASTContext(),
319009e7f20SSebastian Redl                                           DeserializationListener,
320009e7f20SSebastian Redl                                           Preamble));
321925296b4SDouglas Gregor   ModuleManager = static_cast<ASTReader*>(Source.get());
322599313efSDaniel Dunbar   getASTContext().setExternalSource(Source);
323599313efSDaniel Dunbar }
324599313efSDaniel Dunbar 
325599313efSDaniel Dunbar ExternalASTSource *
3260e62c1ccSChris Lattner CompilerInstance::createPCHExternalASTSource(StringRef Path,
327599313efSDaniel Dunbar                                              const std::string &Sysroot,
328ce3a8293SDouglas Gregor                                              bool DisablePCHValidation,
3294a280ff4SArgyrios Kyrtzidis                                              bool AllowPCHWithCompilerErrors,
330599313efSDaniel Dunbar                                              Preprocessor &PP,
33107a89a83SSebastian Redl                                              ASTContext &Context,
332009e7f20SSebastian Redl                                              void *DeserializationListener,
333009e7f20SSebastian Redl                                              bool Preamble) {
334e2778999SDylan Noblesmith   OwningPtr<ASTReader> Reader;
3358835e03cSDouglas Gregor   Reader.reset(new ASTReader(PP, Context,
336c567ba26SDouglas Gregor                              Sysroot.empty() ? "" : Sysroot.c_str(),
337d7c16b25SArgyrios Kyrtzidis                              DisablePCHValidation,
3384a280ff4SArgyrios Kyrtzidis                              AllowPCHWithCompilerErrors));
339599313efSDaniel Dunbar 
34007a89a83SSebastian Redl   Reader->setDeserializationListener(
3413e31c724SSebastian Redl             static_cast<ASTDeserializationListener *>(DeserializationListener));
342009e7f20SSebastian Redl   switch (Reader->ReadAST(Path,
343a6895d8aSDouglas Gregor                           Preamble ? serialization::MK_Preamble
3444b29c16eSDouglas Gregor                                    : serialization::MK_PCH,
3452ec29367SArgyrios Kyrtzidis                           SourceLocation(),
3464b29c16eSDouglas Gregor                           ASTReader::ARR_None)) {
3472c499f65SSebastian Redl   case ASTReader::Success:
348599313efSDaniel Dunbar     // Set the predefines buffer as suggested by the PCH reader. Typically, the
349599313efSDaniel Dunbar     // predefines buffer will be empty.
350599313efSDaniel Dunbar     PP.setPredefines(Reader->getSuggestedPredefines());
351599313efSDaniel Dunbar     return Reader.take();
352599313efSDaniel Dunbar 
3532c499f65SSebastian Redl   case ASTReader::Failure:
354599313efSDaniel Dunbar     // Unrecoverable failure: don't even try to process the input file.
355599313efSDaniel Dunbar     break;
356599313efSDaniel Dunbar 
357c9ad5fb6SDouglas Gregor   case ASTReader::OutOfDate:
358c9ad5fb6SDouglas Gregor   case ASTReader::VersionMismatch:
359c9ad5fb6SDouglas Gregor   case ASTReader::ConfigurationMismatch:
360c9ad5fb6SDouglas Gregor   case ASTReader::HadErrors:
361599313efSDaniel Dunbar     // No suitable PCH file could be found. Return an error.
362599313efSDaniel Dunbar     break;
363599313efSDaniel Dunbar   }
364599313efSDaniel Dunbar 
365599313efSDaniel Dunbar   return 0;
366599313efSDaniel Dunbar }
367f7093b5aSDaniel Dunbar 
368f7093b5aSDaniel Dunbar // Code Completion
369f7093b5aSDaniel Dunbar 
3708e984da8SDouglas Gregor static bool EnableCodeCompletion(Preprocessor &PP,
3718e984da8SDouglas Gregor                                  const std::string &Filename,
3728e984da8SDouglas Gregor                                  unsigned Line,
3738e984da8SDouglas Gregor                                  unsigned Column) {
3748e984da8SDouglas Gregor   // Tell the source manager to chop off the given file at a specific
3758e984da8SDouglas Gregor   // line and column.
3765159f616SChris Lattner   const FileEntry *Entry = PP.getFileManager().getFile(Filename);
3778e984da8SDouglas Gregor   if (!Entry) {
3788e984da8SDouglas Gregor     PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
3798e984da8SDouglas Gregor       << Filename;
3808e984da8SDouglas Gregor     return true;
3818e984da8SDouglas Gregor   }
3828e984da8SDouglas Gregor 
3838e984da8SDouglas Gregor   // Truncate the named file at the given line/column.
3848e984da8SDouglas Gregor   PP.SetCodeCompletionPoint(Entry, Line, Column);
3858e984da8SDouglas Gregor   return false;
3868e984da8SDouglas Gregor }
3878e984da8SDouglas Gregor 
388f7093b5aSDaniel Dunbar void CompilerInstance::createCodeCompletionConsumer() {
389f7093b5aSDaniel Dunbar   const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt;
3908e984da8SDouglas Gregor   if (!CompletionConsumer) {
3912fca3c2cSErik Verbruggen     setCodeCompletionConsumer(
392f7093b5aSDaniel Dunbar       createCodeCompletionConsumer(getPreprocessor(),
393f7093b5aSDaniel Dunbar                                    Loc.FileName, Loc.Line, Loc.Column,
3943292d06aSDmitri Gribenko                                    getFrontendOpts().CodeCompleteOpts,
395f7093b5aSDaniel Dunbar                                    llvm::outs()));
39600a0cf70SDouglas Gregor     if (!CompletionConsumer)
39700a0cf70SDouglas Gregor       return;
3988e984da8SDouglas Gregor   } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName,
3998e984da8SDouglas Gregor                                   Loc.Line, Loc.Column)) {
4002fca3c2cSErik Verbruggen     setCodeCompletionConsumer(0);
4018e984da8SDouglas Gregor     return;
4028e984da8SDouglas Gregor   }
403f09935f1SDouglas Gregor 
404f09935f1SDouglas Gregor   if (CompletionConsumer->isOutputBinary() &&
405f09935f1SDouglas Gregor       llvm::sys::Program::ChangeStdoutToBinary()) {
406f09935f1SDouglas Gregor     getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary);
4072fca3c2cSErik Verbruggen     setCodeCompletionConsumer(0);
408f09935f1SDouglas Gregor   }
409f7093b5aSDaniel Dunbar }
410f7093b5aSDaniel Dunbar 
4115505dff8SKovarththanan Rajaratnam void CompilerInstance::createFrontendTimer() {
4125505dff8SKovarththanan Rajaratnam   FrontendTimer.reset(new llvm::Timer("Clang front-end timer"));
4135505dff8SKovarththanan Rajaratnam }
4145505dff8SKovarththanan Rajaratnam 
415f7093b5aSDaniel Dunbar CodeCompleteConsumer *
416f7093b5aSDaniel Dunbar CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP,
417f7093b5aSDaniel Dunbar                                                const std::string &Filename,
418f7093b5aSDaniel Dunbar                                                unsigned Line,
419f7093b5aSDaniel Dunbar                                                unsigned Column,
4203292d06aSDmitri Gribenko                                                const CodeCompleteOptions &Opts,
4210e62c1ccSChris Lattner                                                raw_ostream &OS) {
4228e984da8SDouglas Gregor   if (EnableCodeCompletion(PP, Filename, Line, Column))
423f7093b5aSDaniel Dunbar     return 0;
424f7093b5aSDaniel Dunbar 
425f7093b5aSDaniel Dunbar   // Set up the creation routine for code-completion.
4263292d06aSDmitri Gribenko   return new PrintingCodeCompleteConsumer(Opts, OS);
427f7093b5aSDaniel Dunbar }
428566eeb2dSDaniel Dunbar 
42969f74f80SDouglas Gregor void CompilerInstance::createSema(TranslationUnitKind TUKind,
4300e93f017SDouglas Gregor                                   CodeCompleteConsumer *CompletionConsumer) {
4310e93f017SDouglas Gregor   TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(),
43269f74f80SDouglas Gregor                          TUKind, CompletionConsumer));
4330e93f017SDouglas Gregor }
4340e93f017SDouglas Gregor 
435566eeb2dSDaniel Dunbar // Output Files
436566eeb2dSDaniel Dunbar 
437d0599970SArgyrios Kyrtzidis void CompilerInstance::addOutputFile(const OutputFile &OutFile) {
438d0599970SArgyrios Kyrtzidis   assert(OutFile.OS && "Attempt to add empty stream to output list!");
439d0599970SArgyrios Kyrtzidis   OutputFiles.push_back(OutFile);
440566eeb2dSDaniel Dunbar }
441566eeb2dSDaniel Dunbar 
4421c558cd7SKovarththanan Rajaratnam void CompilerInstance::clearOutputFiles(bool EraseFiles) {
443d0599970SArgyrios Kyrtzidis   for (std::list<OutputFile>::iterator
444566eeb2dSDaniel Dunbar          it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) {
445d0599970SArgyrios Kyrtzidis     delete it->OS;
446d0599970SArgyrios Kyrtzidis     if (!it->TempFilename.empty()) {
447b5c356a4SAnders Carlsson       if (EraseFiles) {
448b5c356a4SAnders Carlsson         bool existed;
449b5c356a4SAnders Carlsson         llvm::sys::fs::remove(it->TempFilename, existed);
450b5c356a4SAnders Carlsson       } else {
4512c1dd271SDylan Noblesmith         SmallString<128> NewOutFile(it->Filename);
452b5c356a4SAnders Carlsson 
45371731d6bSArgyrios Kyrtzidis         // If '-working-directory' was passed, the output filename should be
45471731d6bSArgyrios Kyrtzidis         // relative to that.
4559ba8fb1eSAnders Carlsson         FileMgr->FixupRelativePath(NewOutFile);
456b5c356a4SAnders Carlsson         if (llvm::error_code ec = llvm::sys::fs::rename(it->TempFilename,
457b5c356a4SAnders Carlsson                                                         NewOutFile.str())) {
4583ef9c447SManuel Klimek           getDiagnostics().Report(diag::err_unable_to_rename_temp)
459b5c356a4SAnders Carlsson             << it->TempFilename << it->Filename << ec.message();
460b5c356a4SAnders Carlsson 
461b5c356a4SAnders Carlsson           bool existed;
462b5c356a4SAnders Carlsson           llvm::sys::fs::remove(it->TempFilename, existed);
463d0599970SArgyrios Kyrtzidis         }
464d0599970SArgyrios Kyrtzidis       }
465d0599970SArgyrios Kyrtzidis     } else if (!it->Filename.empty() && EraseFiles)
466d0599970SArgyrios Kyrtzidis       llvm::sys::Path(it->Filename).eraseFromDisk();
467d0599970SArgyrios Kyrtzidis 
468566eeb2dSDaniel Dunbar   }
469566eeb2dSDaniel Dunbar   OutputFiles.clear();
470566eeb2dSDaniel Dunbar }
471566eeb2dSDaniel Dunbar 
472420b0f1bSDaniel Dunbar llvm::raw_fd_ostream *
473420b0f1bSDaniel Dunbar CompilerInstance::createDefaultOutputFile(bool Binary,
4740e62c1ccSChris Lattner                                           StringRef InFile,
4750e62c1ccSChris Lattner                                           StringRef Extension) {
476420b0f1bSDaniel Dunbar   return createOutputFile(getFrontendOpts().OutputFile, Binary,
477ae77b3dfSDaniel Dunbar                           /*RemoveFileOnSignal=*/true, InFile, Extension,
478ae77b3dfSDaniel Dunbar                           /*UseTemporary=*/true);
479420b0f1bSDaniel Dunbar }
480420b0f1bSDaniel Dunbar 
481420b0f1bSDaniel Dunbar llvm::raw_fd_ostream *
4820e62c1ccSChris Lattner CompilerInstance::createOutputFile(StringRef OutputPath,
483e326f9bbSDaniel Dunbar                                    bool Binary, bool RemoveFileOnSignal,
4840e62c1ccSChris Lattner                                    StringRef InFile,
48508a2bfd2SArgyrios Kyrtzidis                                    StringRef Extension,
486b9c62c07SDaniel Dunbar                                    bool UseTemporary,
487b9c62c07SDaniel Dunbar                                    bool CreateMissingDirectories) {
488d0599970SArgyrios Kyrtzidis   std::string Error, OutputPathName, TempPathName;
489420b0f1bSDaniel Dunbar   llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary,
490e326f9bbSDaniel Dunbar                                               RemoveFileOnSignal,
491420b0f1bSDaniel Dunbar                                               InFile, Extension,
49208a2bfd2SArgyrios Kyrtzidis                                               UseTemporary,
493b9c62c07SDaniel Dunbar                                               CreateMissingDirectories,
494d0599970SArgyrios Kyrtzidis                                               &OutputPathName,
495d0599970SArgyrios Kyrtzidis                                               &TempPathName);
496420b0f1bSDaniel Dunbar   if (!OS) {
4977554699aSDaniel Dunbar     getDiagnostics().Report(diag::err_fe_unable_to_open_output)
4987554699aSDaniel Dunbar       << OutputPath << Error;
4997554699aSDaniel Dunbar     return 0;
500420b0f1bSDaniel Dunbar   }
501420b0f1bSDaniel Dunbar 
502420b0f1bSDaniel Dunbar   // Add the output file -- but don't try to remove "-", since this means we are
503420b0f1bSDaniel Dunbar   // using stdin.
504d0599970SArgyrios Kyrtzidis   addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "",
505d0599970SArgyrios Kyrtzidis                 TempPathName, OS));
506420b0f1bSDaniel Dunbar 
507420b0f1bSDaniel Dunbar   return OS;
508420b0f1bSDaniel Dunbar }
509420b0f1bSDaniel Dunbar 
510420b0f1bSDaniel Dunbar llvm::raw_fd_ostream *
5110e62c1ccSChris Lattner CompilerInstance::createOutputFile(StringRef OutputPath,
512420b0f1bSDaniel Dunbar                                    std::string &Error,
513420b0f1bSDaniel Dunbar                                    bool Binary,
514e326f9bbSDaniel Dunbar                                    bool RemoveFileOnSignal,
5150e62c1ccSChris Lattner                                    StringRef InFile,
5160e62c1ccSChris Lattner                                    StringRef Extension,
51708a2bfd2SArgyrios Kyrtzidis                                    bool UseTemporary,
518b9c62c07SDaniel Dunbar                                    bool CreateMissingDirectories,
519d0599970SArgyrios Kyrtzidis                                    std::string *ResultPathName,
520d0599970SArgyrios Kyrtzidis                                    std::string *TempPathName) {
521b9c62c07SDaniel Dunbar   assert((!CreateMissingDirectories || UseTemporary) &&
522b9c62c07SDaniel Dunbar          "CreateMissingDirectories is only allowed when using temporary files");
523b9c62c07SDaniel Dunbar 
524d0599970SArgyrios Kyrtzidis   std::string OutFile, TempFile;
525420b0f1bSDaniel Dunbar   if (!OutputPath.empty()) {
526420b0f1bSDaniel Dunbar     OutFile = OutputPath;
527420b0f1bSDaniel Dunbar   } else if (InFile == "-") {
528420b0f1bSDaniel Dunbar     OutFile = "-";
529420b0f1bSDaniel Dunbar   } else if (!Extension.empty()) {
530420b0f1bSDaniel Dunbar     llvm::sys::Path Path(InFile);
531420b0f1bSDaniel Dunbar     Path.eraseSuffix();
532420b0f1bSDaniel Dunbar     Path.appendSuffix(Extension);
533420b0f1bSDaniel Dunbar     OutFile = Path.str();
534420b0f1bSDaniel Dunbar   } else {
535420b0f1bSDaniel Dunbar     OutFile = "-";
536420b0f1bSDaniel Dunbar   }
537420b0f1bSDaniel Dunbar 
538e2778999SDylan Noblesmith   OwningPtr<llvm::raw_fd_ostream> OS;
53908a2bfd2SArgyrios Kyrtzidis   std::string OSFile;
54008a2bfd2SArgyrios Kyrtzidis 
54108a2bfd2SArgyrios Kyrtzidis   if (UseTemporary && OutFile != "-") {
542b9c62c07SDaniel Dunbar     // Only create the temporary if the parent directory exists (or create
543b9c62c07SDaniel Dunbar     // missing directories is true) and we can actually write to OutPath,
544b9c62c07SDaniel Dunbar     // otherwise we want to fail early.
545b9c62c07SDaniel Dunbar     SmallString<256> AbsPath(OutputPath);
546b9c62c07SDaniel Dunbar     llvm::sys::fs::make_absolute(AbsPath);
547b9c62c07SDaniel Dunbar     llvm::sys::Path OutPath(AbsPath);
548b9c62c07SDaniel Dunbar     bool ParentExists = false;
549b9c62c07SDaniel Dunbar     if (llvm::sys::fs::exists(llvm::sys::path::parent_path(AbsPath.str()),
550b9c62c07SDaniel Dunbar                               ParentExists))
551b9c62c07SDaniel Dunbar       ParentExists = false;
552f6efe58dSMichael J. Spencer     bool Exists;
553b9c62c07SDaniel Dunbar     if ((CreateMissingDirectories || ParentExists) &&
554b9c62c07SDaniel Dunbar         ((llvm::sys::fs::exists(AbsPath.str(), Exists) || !Exists) ||
555b9c62c07SDaniel Dunbar          (OutPath.isRegularFile() && OutPath.canWrite()))) {
556d0599970SArgyrios Kyrtzidis       // Create a temporary file.
5572c1dd271SDylan Noblesmith       SmallString<128> TempPath;
55808a2bfd2SArgyrios Kyrtzidis       TempPath = OutFile;
55908a2bfd2SArgyrios Kyrtzidis       TempPath += "-%%%%%%%%";
56008a2bfd2SArgyrios Kyrtzidis       int fd;
56108a2bfd2SArgyrios Kyrtzidis       if (llvm::sys::fs::unique_file(TempPath.str(), fd, TempPath,
562f6a6346dSEric Christopher                                      /*makeAbsolute=*/false, 0664)
563f6a6346dSEric Christopher           == llvm::errc::success) {
56408a2bfd2SArgyrios Kyrtzidis         OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true));
56508a2bfd2SArgyrios Kyrtzidis         OSFile = TempFile = TempPath.str();
56608a2bfd2SArgyrios Kyrtzidis       }
567d0599970SArgyrios Kyrtzidis     }
568d0599970SArgyrios Kyrtzidis   }
569d0599970SArgyrios Kyrtzidis 
57008a2bfd2SArgyrios Kyrtzidis   if (!OS) {
57108a2bfd2SArgyrios Kyrtzidis     OSFile = OutFile;
57208a2bfd2SArgyrios Kyrtzidis     OS.reset(
573d0599970SArgyrios Kyrtzidis       new llvm::raw_fd_ostream(OSFile.c_str(), Error,
5742eaef18eSDaniel Dunbar                                (Binary ? llvm::raw_fd_ostream::F_Binary : 0)));
5752eaef18eSDaniel Dunbar     if (!Error.empty())
576420b0f1bSDaniel Dunbar       return 0;
57708a2bfd2SArgyrios Kyrtzidis   }
578420b0f1bSDaniel Dunbar 
579d0599970SArgyrios Kyrtzidis   // Make sure the out stream file gets removed if we crash.
580e326f9bbSDaniel Dunbar   if (RemoveFileOnSignal)
581d0599970SArgyrios Kyrtzidis     llvm::sys::RemoveFileOnSignal(llvm::sys::Path(OSFile));
582d0599970SArgyrios Kyrtzidis 
583420b0f1bSDaniel Dunbar   if (ResultPathName)
584420b0f1bSDaniel Dunbar     *ResultPathName = OutFile;
585d0599970SArgyrios Kyrtzidis   if (TempPathName)
586d0599970SArgyrios Kyrtzidis     *TempPathName = TempFile;
587420b0f1bSDaniel Dunbar 
5882eaef18eSDaniel Dunbar   return OS.take();
589420b0f1bSDaniel Dunbar }
590409e890fSDaniel Dunbar 
591409e890fSDaniel Dunbar // Initialization Utilities
592409e890fSDaniel Dunbar 
5931b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){
5941b3240b0SArgyrios Kyrtzidis   return InitializeSourceManager(Input, getDiagnostics(),
595a686e1b0SDouglas Gregor                                  getFileManager(), getSourceManager(),
596a686e1b0SDouglas Gregor                                  getFrontendOpts());
597409e890fSDaniel Dunbar }
598409e890fSDaniel Dunbar 
5991b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input,
6009c902b55SDavid Blaikie                                                DiagnosticsEngine &Diags,
601409e890fSDaniel Dunbar                                                FileManager &FileMgr,
602409e890fSDaniel Dunbar                                                SourceManager &SourceMgr,
603409e890fSDaniel Dunbar                                                const FrontendOptions &Opts) {
6041b3240b0SArgyrios Kyrtzidis   SrcMgr::CharacteristicKind
605873c8583SArgyrios Kyrtzidis     Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
6061b3240b0SArgyrios Kyrtzidis 
6076566e23eSArgyrios Kyrtzidis   if (Input.isBuffer()) {
6086566e23eSArgyrios Kyrtzidis     SourceMgr.createMainFileIDForMemBuffer(Input.getBuffer(), Kind);
6096566e23eSArgyrios Kyrtzidis     assert(!SourceMgr.getMainFileID().isInvalid() &&
6106566e23eSArgyrios Kyrtzidis            "Couldn't establish MainFileID!");
6116566e23eSArgyrios Kyrtzidis     return true;
6126566e23eSArgyrios Kyrtzidis   }
6136566e23eSArgyrios Kyrtzidis 
6146566e23eSArgyrios Kyrtzidis   StringRef InputFile = Input.getFile();
6156566e23eSArgyrios Kyrtzidis 
6167c06d866SArgyrios Kyrtzidis   // Figure out where to get and map in the main file.
6177c06d866SArgyrios Kyrtzidis   if (InputFile != "-") {
6185159f616SChris Lattner     const FileEntry *File = FileMgr.getFile(InputFile);
61952765215SDan Gohman     if (!File) {
620409e890fSDaniel Dunbar       Diags.Report(diag::err_fe_error_reading) << InputFile;
621409e890fSDaniel Dunbar       return false;
622409e890fSDaniel Dunbar     }
623e2951f48SDaniel Dunbar 
624e2951f48SDaniel Dunbar     // The natural SourceManager infrastructure can't currently handle named
625e2951f48SDaniel Dunbar     // pipes, but we would at least like to accept them for the main
626e2951f48SDaniel Dunbar     // file. Detect them here, read them with the more generic MemoryBuffer
627e2951f48SDaniel Dunbar     // function, and simply override their contents as we do for STDIN.
628e2951f48SDaniel Dunbar     if (File->isNamedPipe()) {
629e2951f48SDaniel Dunbar       OwningPtr<llvm::MemoryBuffer> MB;
630e2951f48SDaniel Dunbar       if (llvm::error_code ec = llvm::MemoryBuffer::getFile(InputFile, MB)) {
631e2951f48SDaniel Dunbar         Diags.Report(diag::err_cannot_open_file) << InputFile << ec.message();
632e2951f48SDaniel Dunbar         return false;
633e2951f48SDaniel Dunbar       }
634db0745abSDaniel Dunbar 
635db0745abSDaniel Dunbar       // Create a new virtual file that will have the correct size.
636db0745abSDaniel Dunbar       File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0);
637e2951f48SDaniel Dunbar       SourceMgr.overrideFileContents(File, MB.take());
638e2951f48SDaniel Dunbar     }
639db0745abSDaniel Dunbar 
640db0745abSDaniel Dunbar     SourceMgr.createMainFileID(File, Kind);
641409e890fSDaniel Dunbar   } else {
642e2778999SDylan Noblesmith     OwningPtr<llvm::MemoryBuffer> SB;
643d9da7a1fSMichael J. Spencer     if (llvm::MemoryBuffer::getSTDIN(SB)) {
644f25faaafSMichael J. Spencer       // FIXME: Give ec.message() in this diag.
645409e890fSDaniel Dunbar       Diags.Report(diag::err_fe_error_reading_stdin);
646409e890fSDaniel Dunbar       return false;
647409e890fSDaniel Dunbar     }
6482f76cd75SDan Gohman     const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(),
6495159f616SChris Lattner                                                    SB->getBufferSize(), 0);
650a686e1b0SDouglas Gregor     SourceMgr.createMainFileID(File, Kind);
651d9da7a1fSMichael J. Spencer     SourceMgr.overrideFileContents(File, SB.take());
652409e890fSDaniel Dunbar   }
653409e890fSDaniel Dunbar 
65452765215SDan Gohman   assert(!SourceMgr.getMainFileID().isInvalid() &&
65552765215SDan Gohman          "Couldn't establish MainFileID!");
656409e890fSDaniel Dunbar   return true;
657409e890fSDaniel Dunbar }
6584f2bc55dSDaniel Dunbar 
6594f2bc55dSDaniel Dunbar // High-Level Operations
6604f2bc55dSDaniel Dunbar 
6614f2bc55dSDaniel Dunbar bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
6624f2bc55dSDaniel Dunbar   assert(hasDiagnostics() && "Diagnostics engine is not initialized!");
6634f2bc55dSDaniel Dunbar   assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!");
6644f2bc55dSDaniel Dunbar   assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!");
6654f2bc55dSDaniel Dunbar 
6664f2bc55dSDaniel Dunbar   // FIXME: Take this as an argument, once all the APIs we used have moved to
6674f2bc55dSDaniel Dunbar   // taking it as an input instead of hard-coding llvm::errs.
6680e62c1ccSChris Lattner   raw_ostream &OS = llvm::errs();
6694f2bc55dSDaniel Dunbar 
6704f2bc55dSDaniel Dunbar   // Create the target instance.
671f8715de5SDouglas Gregor   setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), &getTargetOpts()));
6724f2bc55dSDaniel Dunbar   if (!hasTarget())
6734f2bc55dSDaniel Dunbar     return false;
6744f2bc55dSDaniel Dunbar 
6754f2bc55dSDaniel Dunbar   // Inform the target of the language options.
6764f2bc55dSDaniel Dunbar   //
6774f2bc55dSDaniel Dunbar   // FIXME: We shouldn't need to do this, the target should be immutable once
6784f2bc55dSDaniel Dunbar   // created. This complexity should be lifted elsewhere.
6794f2bc55dSDaniel Dunbar   getTarget().setForcedLangOptions(getLangOpts());
6804f2bc55dSDaniel Dunbar 
68129898f45SFariborz Jahanian   // rewriter project will change target built-in bool type from its default.
68229898f45SFariborz Jahanian   if (getFrontendOpts().ProgramAction == frontend::RewriteObjC)
68329898f45SFariborz Jahanian     getTarget().noSignedCharForObjCBool();
68429898f45SFariborz Jahanian 
6854f2bc55dSDaniel Dunbar   // Validate/process some options.
6864f2bc55dSDaniel Dunbar   if (getHeaderSearchOpts().Verbose)
6874f2bc55dSDaniel Dunbar     OS << "clang -cc1 version " CLANG_VERSION_STRING
6884f2bc55dSDaniel Dunbar        << " based upon " << PACKAGE_STRING
6898188c8a1SSebastian Pop        << " default target " << llvm::sys::getDefaultTargetTriple() << "\n";
6904f2bc55dSDaniel Dunbar 
6914f2bc55dSDaniel Dunbar   if (getFrontendOpts().ShowTimers)
6924f2bc55dSDaniel Dunbar     createFrontendTimer();
6934f2bc55dSDaniel Dunbar 
694171b780cSDouglas Gregor   if (getFrontendOpts().ShowStats)
695171b780cSDouglas Gregor     llvm::EnableStatistics();
696171b780cSDouglas Gregor 
6974f2bc55dSDaniel Dunbar   for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) {
6984f2bc55dSDaniel Dunbar     // Reset the ID tables if we are reusing the SourceManager.
699aed46fcbSDaniel Dunbar     if (hasSourceManager())
7004f2bc55dSDaniel Dunbar       getSourceManager().clearIDTables();
7014f2bc55dSDaniel Dunbar 
70232fbe312SDouglas Gregor     if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) {
7034f2bc55dSDaniel Dunbar       Act.Execute();
7044f2bc55dSDaniel Dunbar       Act.EndSourceFile();
7054f2bc55dSDaniel Dunbar     }
7064f2bc55dSDaniel Dunbar   }
7074f2bc55dSDaniel Dunbar 
7087910d7b7SArgyrios Kyrtzidis   // Notify the diagnostic client that all files were processed.
7097910d7b7SArgyrios Kyrtzidis   getDiagnostics().getClient()->finish();
7107910d7b7SArgyrios Kyrtzidis 
711198cb4dfSChris Lattner   if (getDiagnosticOpts().ShowCarets) {
712c79346a5SArgyrios Kyrtzidis     // We can have multiple diagnostics sharing one diagnostic client.
713c79346a5SArgyrios Kyrtzidis     // Get the total number of warnings/errors from the client.
714c79346a5SArgyrios Kyrtzidis     unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings();
715c79346a5SArgyrios Kyrtzidis     unsigned NumErrors = getDiagnostics().getClient()->getNumErrors();
716198cb4dfSChris Lattner 
717198cb4dfSChris Lattner     if (NumWarnings)
718198cb4dfSChris Lattner       OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s");
719198cb4dfSChris Lattner     if (NumWarnings && NumErrors)
720198cb4dfSChris Lattner       OS << " and ";
721198cb4dfSChris Lattner     if (NumErrors)
722198cb4dfSChris Lattner       OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s");
723198cb4dfSChris Lattner     if (NumWarnings || NumErrors)
724198cb4dfSChris Lattner       OS << " generated.\n";
725198cb4dfSChris Lattner   }
7264f2bc55dSDaniel Dunbar 
727aed46fcbSDaniel Dunbar   if (getFrontendOpts().ShowStats && hasFileManager()) {
7284f2bc55dSDaniel Dunbar     getFileManager().PrintStats();
7294f2bc55dSDaniel Dunbar     OS << "\n";
7304f2bc55dSDaniel Dunbar   }
7314f2bc55dSDaniel Dunbar 
732bc467933SArgyrios Kyrtzidis   return !getDiagnostics().getClient()->getNumErrors();
7334f2bc55dSDaniel Dunbar }
7344f2bc55dSDaniel Dunbar 
735faeb1d46SDouglas Gregor /// \brief Determine the appropriate source input kind based on language
736faeb1d46SDouglas Gregor /// options.
737faeb1d46SDouglas Gregor static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) {
738faeb1d46SDouglas Gregor   if (LangOpts.OpenCL)
739faeb1d46SDouglas Gregor     return IK_OpenCL;
740faeb1d46SDouglas Gregor   if (LangOpts.CUDA)
741faeb1d46SDouglas Gregor     return IK_CUDA;
742faeb1d46SDouglas Gregor   if (LangOpts.ObjC1)
743faeb1d46SDouglas Gregor     return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC;
744faeb1d46SDouglas Gregor   return LangOpts.CPlusPlus? IK_CXX : IK_C;
745faeb1d46SDouglas Gregor }
746faeb1d46SDouglas Gregor 
74751e0b541SDouglas Gregor namespace {
748514b636aSDouglas Gregor   struct CompileModuleMapData {
749514b636aSDouglas Gregor     CompilerInstance &Instance;
750514b636aSDouglas Gregor     GenerateModuleAction &CreateModuleAction;
751514b636aSDouglas Gregor   };
752514b636aSDouglas Gregor }
753514b636aSDouglas Gregor 
754514b636aSDouglas Gregor /// \brief Helper function that executes the module-generating action under
755514b636aSDouglas Gregor /// a crash recovery context.
756514b636aSDouglas Gregor static void doCompileMapModule(void *UserData) {
757514b636aSDouglas Gregor   CompileModuleMapData &Data
758514b636aSDouglas Gregor     = *reinterpret_cast<CompileModuleMapData *>(UserData);
759514b636aSDouglas Gregor   Data.Instance.ExecuteAction(Data.CreateModuleAction);
760514b636aSDouglas Gregor }
761514b636aSDouglas Gregor 
762514b636aSDouglas Gregor /// \brief Compile a module file for the given module, using the options
763514b636aSDouglas Gregor /// provided by the importing compiler instance.
764faeb1d46SDouglas Gregor static void compileModule(CompilerInstance &ImportingInstance,
765af8f0263SDouglas Gregor                           SourceLocation ImportLoc,
766de3ef502SDouglas Gregor                           Module *Module,
7676dc57927SDouglas Gregor                           StringRef ModuleFileName) {
768e212489fSDouglas Gregor   llvm::LockFileManager Locked(ModuleFileName);
76954a88810SDouglas Gregor   switch (Locked) {
770e212489fSDouglas Gregor   case llvm::LockFileManager::LFS_Error:
77154a88810SDouglas Gregor     return;
77254a88810SDouglas Gregor 
773e212489fSDouglas Gregor   case llvm::LockFileManager::LFS_Owned:
77454a88810SDouglas Gregor     // We're responsible for building the module ourselves. Do so below.
77554a88810SDouglas Gregor     break;
77654a88810SDouglas Gregor 
777e212489fSDouglas Gregor   case llvm::LockFileManager::LFS_Shared:
77854a88810SDouglas Gregor     // Someone else is responsible for building the module. Wait for them to
77954a88810SDouglas Gregor     // finish.
78054a88810SDouglas Gregor     Locked.waitForUnlock();
781188dbef2SDouglas Gregor     return;
78254a88810SDouglas Gregor   }
78354a88810SDouglas Gregor 
784514b636aSDouglas Gregor   ModuleMap &ModMap
785514b636aSDouglas Gregor     = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
786514b636aSDouglas Gregor 
787faeb1d46SDouglas Gregor   // Construct a compiler invocation for creating this module.
788c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<CompilerInvocation> Invocation
789faeb1d46SDouglas Gregor     (new CompilerInvocation(ImportingInstance.getInvocation()));
79044bf68d8SDouglas Gregor 
791f545f67dSDouglas Gregor   PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
792f545f67dSDouglas Gregor 
79344bf68d8SDouglas Gregor   // For any options that aren't intended to affect how a module is built,
79444bf68d8SDouglas Gregor   // reset them to their default values.
7958cf47df7STed Kremenek   Invocation->getLangOpts()->resetNonModularOptions();
796f545f67dSDouglas Gregor   PPOpts.resetNonModularOptions();
79744bf68d8SDouglas Gregor 
7987d106e42SDouglas Gregor   // Note the name of the module we're building.
7996dc57927SDouglas Gregor   Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName();
8007d106e42SDouglas Gregor 
8017a626570SDouglas Gregor   // Make sure that the failed-module structure has been allocated in
8027a626570SDouglas Gregor   // the importing instance, and propagate the pointer to the newly-created
8037a626570SDouglas Gregor   // instance.
8047a626570SDouglas Gregor   PreprocessorOptions &ImportingPPOpts
8057a626570SDouglas Gregor     = ImportingInstance.getInvocation().getPreprocessorOpts();
8067a626570SDouglas Gregor   if (!ImportingPPOpts.FailedModules)
8077a626570SDouglas Gregor     ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet;
8087a626570SDouglas Gregor   PPOpts.FailedModules = ImportingPPOpts.FailedModules;
8097a626570SDouglas Gregor 
810514b636aSDouglas Gregor   // If there is a module map file, build the module using the module map.
811514b636aSDouglas Gregor   // Set up the inputs/outputs so that we build the module from its umbrella
812514b636aSDouglas Gregor   // header.
813514b636aSDouglas Gregor   FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
814514b636aSDouglas Gregor   FrontendOpts.OutputFile = ModuleFileName.str();
815514b636aSDouglas Gregor   FrontendOpts.DisableFree = false;
816514b636aSDouglas Gregor   FrontendOpts.Inputs.clear();
817f545f67dSDouglas Gregor   InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts());
818f545f67dSDouglas Gregor 
819f545f67dSDouglas Gregor   // Get or create the module map that we'll use to build this module.
8202c1dd271SDylan Noblesmith   SmallString<128> TempModuleMapFileName;
821f545f67dSDouglas Gregor   if (const FileEntry *ModuleMapFile
822f545f67dSDouglas Gregor                                   = ModMap.getContainingModuleMapFile(Module)) {
823f545f67dSDouglas Gregor     // Use the module map where this module resides.
82432fbe312SDouglas Gregor     FrontendOpts.Inputs.push_back(FrontendInputFile(ModuleMapFile->getName(),
82532fbe312SDouglas Gregor                                                     IK));
826f545f67dSDouglas Gregor   } else {
827f545f67dSDouglas Gregor     // Create a temporary module map file.
828f545f67dSDouglas Gregor     TempModuleMapFileName = Module->Name;
829f545f67dSDouglas Gregor     TempModuleMapFileName += "-%%%%%%%%.map";
830f545f67dSDouglas Gregor     int FD;
831f545f67dSDouglas Gregor     if (llvm::sys::fs::unique_file(TempModuleMapFileName.str(), FD,
832f545f67dSDouglas Gregor                                    TempModuleMapFileName,
83319f9f7bcSDouglas Gregor                                    /*makeAbsolute=*/true)
8342f554c4cSDouglas Gregor           != llvm::errc::success) {
835ee78d3e0SDouglas Gregor       ImportingInstance.getDiagnostics().Report(diag::err_module_map_temp_file)
836ee78d3e0SDouglas Gregor         << TempModuleMapFileName;
837f545f67dSDouglas Gregor       return;
8382f554c4cSDouglas Gregor     }
839f545f67dSDouglas Gregor     // Print the module map to this file.
840f545f67dSDouglas Gregor     llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true);
841f545f67dSDouglas Gregor     Module->print(OS);
842514b636aSDouglas Gregor     FrontendOpts.Inputs.push_back(
84332fbe312SDouglas Gregor       FrontendInputFile(TempModuleMapFileName.str().str(), IK));
844f545f67dSDouglas Gregor   }
845f545f67dSDouglas Gregor 
846f545f67dSDouglas Gregor   // Don't free the remapped file buffers; they are owned by our caller.
847f545f67dSDouglas Gregor   PPOpts.RetainRemappedFileBuffers = true;
848514b636aSDouglas Gregor 
849514b636aSDouglas Gregor   Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
850514b636aSDouglas Gregor   assert(ImportingInstance.getInvocation().getModuleHash() ==
851514b636aSDouglas Gregor          Invocation->getModuleHash() && "Module hash mismatch!");
852514b636aSDouglas Gregor 
853514b636aSDouglas Gregor   // Construct a compiler instance that will be used to actually create the
854514b636aSDouglas Gregor   // module.
855514b636aSDouglas Gregor   CompilerInstance Instance;
856514b636aSDouglas Gregor   Instance.setInvocation(&*Invocation);
857514b636aSDouglas Gregor   Instance.createDiagnostics(/*argc=*/0, /*argv=*/0,
858514b636aSDouglas Gregor                              &ImportingInstance.getDiagnosticClient(),
859514b636aSDouglas Gregor                              /*ShouldOwnClient=*/true,
860514b636aSDouglas Gregor                              /*ShouldCloneClient=*/true);
861514b636aSDouglas Gregor 
86263365431SDouglas Gregor   // Note that this module is part of the module build stack, so that we
863af8f0263SDouglas Gregor   // can detect cycles in the module graph.
864af8f0263SDouglas Gregor   Instance.createFileManager(); // FIXME: Adopt file manager from importer?
865af8f0263SDouglas Gregor   Instance.createSourceManager(Instance.getFileManager());
866af8f0263SDouglas Gregor   SourceManager &SourceMgr = Instance.getSourceManager();
86763365431SDouglas Gregor   SourceMgr.setModuleBuildStack(
86863365431SDouglas Gregor     ImportingInstance.getSourceManager().getModuleBuildStack());
86963365431SDouglas Gregor   SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(),
870af8f0263SDouglas Gregor     FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));
871af8f0263SDouglas Gregor 
872af8f0263SDouglas Gregor 
873514b636aSDouglas Gregor   // Construct a module-generating action.
874514b636aSDouglas Gregor   GenerateModuleAction CreateModuleAction;
875514b636aSDouglas Gregor 
876514b636aSDouglas Gregor   // Execute the action to actually build the module in-place. Use a separate
877514b636aSDouglas Gregor   // thread so that we get a stack large enough.
878514b636aSDouglas Gregor   const unsigned ThreadStackSize = 8 << 20;
879514b636aSDouglas Gregor   llvm::CrashRecoveryContext CRC;
880514b636aSDouglas Gregor   CompileModuleMapData Data = { Instance, CreateModuleAction };
881514b636aSDouglas Gregor   CRC.RunSafelyOnThread(&doCompileMapModule, &Data, ThreadStackSize);
882514b636aSDouglas Gregor 
883f545f67dSDouglas Gregor   // Delete the temporary module map file.
884f545f67dSDouglas Gregor   // FIXME: Even though we're executing under crash protection, it would still
885f545f67dSDouglas Gregor   // be nice to do this with RemoveFileOnSignal when we can. However, that
886f545f67dSDouglas Gregor   // doesn't make sense for all clients, so clean this up manually.
88713afbf42SBenjamin Kramer   Instance.clearOutputFiles(/*EraseFiles=*/true);
888f545f67dSDouglas Gregor   if (!TempModuleMapFileName.empty())
889f545f67dSDouglas Gregor     llvm::sys::Path(TempModuleMapFileName).eraseFromDisk();
890faeb1d46SDouglas Gregor }
891faeb1d46SDouglas Gregor 
8927a626570SDouglas Gregor ModuleLoadResult
8937a626570SDouglas Gregor CompilerInstance::loadModule(SourceLocation ImportLoc,
894ff2be53fSDouglas Gregor                              ModuleIdPath Path,
895bcfc7d02SDouglas Gregor                              Module::NameVisibilityKind Visibility,
896bcfc7d02SDouglas Gregor                              bool IsInclusionDirective) {
8971805b8a4SDouglas Gregor   // If we've already handled this import, just return the cached result.
8981805b8a4SDouglas Gregor   // This one-element cache is important to eliminate redundant diagnostics
8991805b8a4SDouglas Gregor   // when both the preprocessor and parser see the same import declaration.
900ff2be53fSDouglas Gregor   if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) {
901ff2be53fSDouglas Gregor     // Make the named module visible.
902ff2be53fSDouglas Gregor     if (LastModuleImportResult)
903ff2be53fSDouglas Gregor       ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility);
90469021974SDouglas Gregor     return LastModuleImportResult;
905ff2be53fSDouglas Gregor   }
9061805b8a4SDouglas Gregor 
90708142534SDouglas Gregor   // Determine what file we're searching from.
90871944203SDouglas Gregor   StringRef ModuleName = Path[0].first->getName();
90971944203SDouglas Gregor   SourceLocation ModuleNameLoc = Path[0].second;
91071944203SDouglas Gregor 
911de3ef502SDouglas Gregor   clang::Module *Module = 0;
9125196bc6bSDouglas Gregor 
9135196bc6bSDouglas Gregor   // If we don't already have information on this module, load the module now.
914de3ef502SDouglas Gregor   llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known
91569021974SDouglas Gregor     = KnownModules.find(Path[0].first);
9162537a364SDouglas Gregor   if (Known != KnownModules.end()) {
9172537a364SDouglas Gregor     // Retrieve the cached top-level module.
9182537a364SDouglas Gregor     Module = Known->second;
9192537a364SDouglas Gregor   } else if (ModuleName == getLangOpts().CurrentModule) {
9202537a364SDouglas Gregor     // This is the module we're building.
9212537a364SDouglas Gregor     Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName);
9222537a364SDouglas Gregor     Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
9232537a364SDouglas Gregor   } else {
9245196bc6bSDouglas Gregor     // Search for a module with the given name.
925279a6c37SDouglas Gregor     Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
9261735f4e7SDouglas Gregor     std::string ModuleFileName;
927279a6c37SDouglas Gregor     if (Module)
928279a6c37SDouglas Gregor       ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module);
929279a6c37SDouglas Gregor     else
930279a6c37SDouglas Gregor       ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName);
931faeb1d46SDouglas Gregor 
932279a6c37SDouglas Gregor     if (ModuleFileName.empty()) {
933279a6c37SDouglas Gregor       getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
934279a6c37SDouglas Gregor         << ModuleName
935279a6c37SDouglas Gregor         << SourceRange(ImportLoc, ModuleNameLoc);
936279a6c37SDouglas Gregor       LastModuleImportLoc = ImportLoc;
9377a626570SDouglas Gregor       LastModuleImportResult = ModuleLoadResult();
9387a626570SDouglas Gregor       return LastModuleImportResult;
939279a6c37SDouglas Gregor     }
940279a6c37SDouglas Gregor 
941279a6c37SDouglas Gregor     const FileEntry *ModuleFile
942279a6c37SDouglas Gregor       = getFileManager().getFile(ModuleFileName, /*OpenFile=*/false,
943279a6c37SDouglas Gregor                                  /*CacheFailure=*/false);
944faeb1d46SDouglas Gregor     bool BuildingModule = false;
9456dc57927SDouglas Gregor     if (!ModuleFile && Module) {
9466dc57927SDouglas Gregor       // The module is not cached, but we have a module map from which we can
9476dc57927SDouglas Gregor       // build the module.
948dff0e892SDouglas Gregor 
949dff0e892SDouglas Gregor       // Check whether there is a cycle in the module graph.
95063365431SDouglas Gregor       ModuleBuildStack Path = getSourceManager().getModuleBuildStack();
95163365431SDouglas Gregor       ModuleBuildStack::iterator Pos = Path.begin(), PosEnd = Path.end();
952af8f0263SDouglas Gregor       for (; Pos != PosEnd; ++Pos) {
953af8f0263SDouglas Gregor         if (Pos->first == ModuleName)
954af8f0263SDouglas Gregor           break;
955af8f0263SDouglas Gregor       }
956af8f0263SDouglas Gregor 
957af8f0263SDouglas Gregor       if (Pos != PosEnd) {
9582c1dd271SDylan Noblesmith         SmallString<256> CyclePath;
959af8f0263SDouglas Gregor         for (; Pos != PosEnd; ++Pos) {
960af8f0263SDouglas Gregor           CyclePath += Pos->first;
961dff0e892SDouglas Gregor           CyclePath += " -> ";
962dff0e892SDouglas Gregor         }
96371944203SDouglas Gregor         CyclePath += ModuleName;
964dff0e892SDouglas Gregor 
965dff0e892SDouglas Gregor         getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle)
96671944203SDouglas Gregor           << ModuleName << CyclePath;
9677a626570SDouglas Gregor         return ModuleLoadResult();
9687a626570SDouglas Gregor       }
9697a626570SDouglas Gregor 
9707a626570SDouglas Gregor       // Check whether we have already attempted to build this module (but
9717a626570SDouglas Gregor       // failed).
9727a626570SDouglas Gregor       if (getPreprocessorOpts().FailedModules &&
9737a626570SDouglas Gregor           getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) {
9747a626570SDouglas Gregor         getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built)
9757a626570SDouglas Gregor           << ModuleName
9767a626570SDouglas Gregor           << SourceRange(ImportLoc, ModuleNameLoc);
9777a626570SDouglas Gregor 
9787a626570SDouglas Gregor         return ModuleLoadResult();
979dff0e892SDouglas Gregor       }
980dff0e892SDouglas Gregor 
981faeb1d46SDouglas Gregor       BuildingModule = true;
982af8f0263SDouglas Gregor       compileModule(*this, ModuleNameLoc, Module, ModuleFileName);
983ca295457SDouglas Gregor       ModuleFile = FileMgr->getFile(ModuleFileName);
9847a626570SDouglas Gregor 
985*0f2b4635SDouglas Gregor       if (!ModuleFile && getPreprocessorOpts().FailedModules)
9867a626570SDouglas Gregor         getPreprocessorOpts().FailedModules->addFailed(ModuleName);
987faeb1d46SDouglas Gregor     }
988faeb1d46SDouglas Gregor 
98908142534SDouglas Gregor     if (!ModuleFile) {
990faeb1d46SDouglas Gregor       getDiagnostics().Report(ModuleNameLoc,
991faeb1d46SDouglas Gregor                               BuildingModule? diag::err_module_not_built
992faeb1d46SDouglas Gregor                                             : diag::err_module_not_found)
99371944203SDouglas Gregor         << ModuleName
99408142534SDouglas Gregor         << SourceRange(ImportLoc, ModuleNameLoc);
9957a626570SDouglas Gregor       return ModuleLoadResult();
99608142534SDouglas Gregor     }
99708142534SDouglas Gregor 
99808142534SDouglas Gregor     // If we don't already have an ASTReader, create one now.
99908142534SDouglas Gregor     if (!ModuleManager) {
100021931efcSDouglas Gregor       if (!hasASTContext())
100121931efcSDouglas Gregor         createASTContext();
100221931efcSDouglas Gregor 
100308142534SDouglas Gregor       std::string Sysroot = getHeaderSearchOpts().Sysroot;
100408142534SDouglas Gregor       const PreprocessorOptions &PPOpts = getPreprocessorOpts();
10058835e03cSDouglas Gregor       ModuleManager = new ASTReader(getPreprocessor(), *Context,
100608142534SDouglas Gregor                                     Sysroot.empty() ? "" : Sysroot.c_str(),
1007d7c16b25SArgyrios Kyrtzidis                                     PPOpts.DisablePCHValidation);
100821931efcSDouglas Gregor       if (hasASTConsumer()) {
100908142534SDouglas Gregor         ModuleManager->setDeserializationListener(
101008142534SDouglas Gregor           getASTConsumer().GetASTDeserializationListener());
101108142534SDouglas Gregor         getASTContext().setASTMutationListener(
101208142534SDouglas Gregor           getASTConsumer().GetASTMutationListener());
1013cb28f9d7SDouglas Gregor         getPreprocessor().setPPMutationListener(
1014cb28f9d7SDouglas Gregor           getASTConsumer().GetPPMutationListener());
101521931efcSDouglas Gregor       }
1016e2778999SDylan Noblesmith       OwningPtr<ExternalASTSource> Source;
101708142534SDouglas Gregor       Source.reset(ModuleManager);
101808142534SDouglas Gregor       getASTContext().setExternalSource(Source);
101921931efcSDouglas Gregor       if (hasSema())
102008142534SDouglas Gregor         ModuleManager->InitializeSema(getSema());
10216137d32cSDouglas Gregor       if (hasASTConsumer())
10226137d32cSDouglas Gregor         ModuleManager->StartTranslationUnit(&getASTConsumer());
102308142534SDouglas Gregor     }
102408142534SDouglas Gregor 
102508142534SDouglas Gregor     // Try to load the module we found.
1026188dbef2SDouglas Gregor     unsigned ARRFlags = ASTReader::ARR_None;
1027188dbef2SDouglas Gregor     if (Module)
1028188dbef2SDouglas Gregor       ARRFlags |= ASTReader::ARR_OutOfDate;
102908142534SDouglas Gregor     switch (ModuleManager->ReadAST(ModuleFile->getName(),
10302ec29367SArgyrios Kyrtzidis                                    serialization::MK_Module, ImportLoc,
1031188dbef2SDouglas Gregor                                    ARRFlags)) {
103208142534SDouglas Gregor     case ASTReader::Success:
103308142534SDouglas Gregor       break;
103408142534SDouglas Gregor 
1035188dbef2SDouglas Gregor     case ASTReader::OutOfDate: {
1036188dbef2SDouglas Gregor       // The module file is out-of-date. Rebuild it.
1037188dbef2SDouglas Gregor       getFileManager().invalidateCache(ModuleFile);
1038188dbef2SDouglas Gregor       bool Existed;
1039188dbef2SDouglas Gregor       llvm::sys::fs::remove(ModuleFileName, Existed);
10407a626570SDouglas Gregor 
10417a626570SDouglas Gregor       // Check whether we have already attempted to build this module (but
10427a626570SDouglas Gregor       // failed).
10437a626570SDouglas Gregor       if (getPreprocessorOpts().FailedModules &&
10447a626570SDouglas Gregor           getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) {
10457a626570SDouglas Gregor         getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built)
10467a626570SDouglas Gregor           << ModuleName
10477a626570SDouglas Gregor           << SourceRange(ImportLoc, ModuleNameLoc);
10487a626570SDouglas Gregor 
10497a626570SDouglas Gregor         return ModuleLoadResult();
10507a626570SDouglas Gregor       }
10517a626570SDouglas Gregor 
1052af8f0263SDouglas Gregor       compileModule(*this, ModuleNameLoc, Module, ModuleFileName);
1053188dbef2SDouglas Gregor 
1054188dbef2SDouglas Gregor       // Try loading the module again.
1055188dbef2SDouglas Gregor       ModuleFile = FileMgr->getFile(ModuleFileName);
1056188dbef2SDouglas Gregor       if (!ModuleFile ||
1057188dbef2SDouglas Gregor           ModuleManager->ReadAST(ModuleFileName,
10582ec29367SArgyrios Kyrtzidis                                  serialization::MK_Module, ImportLoc,
1059188dbef2SDouglas Gregor                                  ASTReader::ARR_None) != ASTReader::Success) {
1060*0f2b4635SDouglas Gregor         if (getPreprocessorOpts().FailedModules)
10617a626570SDouglas Gregor           getPreprocessorOpts().FailedModules->addFailed(ModuleName);
1062188dbef2SDouglas Gregor         KnownModules[Path[0].first] = 0;
10637a626570SDouglas Gregor         return ModuleLoadResult();
1064188dbef2SDouglas Gregor       }
1065188dbef2SDouglas Gregor 
1066188dbef2SDouglas Gregor       // Okay, we've rebuilt and now loaded the module.
1067188dbef2SDouglas Gregor       break;
1068188dbef2SDouglas Gregor     }
1069188dbef2SDouglas Gregor 
1070c9ad5fb6SDouglas Gregor     case ASTReader::VersionMismatch:
1071c9ad5fb6SDouglas Gregor     case ASTReader::ConfigurationMismatch:
1072c9ad5fb6SDouglas Gregor     case ASTReader::HadErrors:
107308142534SDouglas Gregor       // FIXME: The ASTReader will already have complained, but can we showhorn
107408142534SDouglas Gregor       // that diagnostic information into a more useful form?
107569021974SDouglas Gregor       KnownModules[Path[0].first] = 0;
10767a626570SDouglas Gregor       return ModuleLoadResult();
107708142534SDouglas Gregor 
107808142534SDouglas Gregor     case ASTReader::Failure:
107969021974SDouglas Gregor       // Already complained, but note now that we failed.
108069021974SDouglas Gregor       KnownModules[Path[0].first] = 0;
10817a626570SDouglas Gregor       return ModuleLoadResult();
108208142534SDouglas Gregor     }
108308142534SDouglas Gregor 
108469021974SDouglas Gregor     if (!Module) {
108569021974SDouglas Gregor       // If we loaded the module directly, without finding a module map first,
108669021974SDouglas Gregor       // we'll have loaded the module's information from the module itself.
108769021974SDouglas Gregor       Module = PP->getHeaderSearchInfo().getModuleMap()
108869021974SDouglas Gregor                  .findModule((Path[0].first->getName()));
10895196bc6bSDouglas Gregor     }
109043af5132SArgyrios Kyrtzidis 
109143af5132SArgyrios Kyrtzidis     if (Module)
109243af5132SArgyrios Kyrtzidis       Module->setASTFile(ModuleFile);
10935196bc6bSDouglas Gregor 
109469021974SDouglas Gregor     // Cache the result of this top-level module lookup for later.
109569021974SDouglas Gregor     Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
109669021974SDouglas Gregor   }
109769021974SDouglas Gregor 
109869021974SDouglas Gregor   // If we never found the module, fail.
109969021974SDouglas Gregor   if (!Module)
11007a626570SDouglas Gregor     return ModuleLoadResult();
110169021974SDouglas Gregor 
11025196bc6bSDouglas Gregor   // Verify that the rest of the module path actually corresponds to
11035196bc6bSDouglas Gregor   // a submodule.
110469021974SDouglas Gregor   if (Path.size() > 1) {
11055196bc6bSDouglas Gregor     for (unsigned I = 1, N = Path.size(); I != N; ++I) {
11065196bc6bSDouglas Gregor       StringRef Name = Path[I].first->getName();
1107eb90e830SDouglas Gregor       clang::Module *Sub = Module->findSubmodule(Name);
11085196bc6bSDouglas Gregor 
1109eb90e830SDouglas Gregor       if (!Sub) {
11105196bc6bSDouglas Gregor         // Attempt to perform typo correction to find a module name that works.
11115196bc6bSDouglas Gregor         llvm::SmallVector<StringRef, 2> Best;
11125196bc6bSDouglas Gregor         unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
11135196bc6bSDouglas Gregor 
1114eb90e830SDouglas Gregor         for (clang::Module::submodule_iterator J = Module->submodule_begin(),
1115eb90e830SDouglas Gregor                                             JEnd = Module->submodule_end();
1116eb44edadSMatt Beaumont-Gay              J != JEnd; ++J) {
1117eb90e830SDouglas Gregor           unsigned ED = Name.edit_distance((*J)->Name,
11185196bc6bSDouglas Gregor                                            /*AllowReplacements=*/true,
11195196bc6bSDouglas Gregor                                            BestEditDistance);
11205196bc6bSDouglas Gregor           if (ED <= BestEditDistance) {
1121eb90e830SDouglas Gregor             if (ED < BestEditDistance) {
11225196bc6bSDouglas Gregor               Best.clear();
1123eb90e830SDouglas Gregor               BestEditDistance = ED;
1124eb90e830SDouglas Gregor             }
1125eb90e830SDouglas Gregor 
1126eb90e830SDouglas Gregor             Best.push_back((*J)->Name);
11275196bc6bSDouglas Gregor           }
11285196bc6bSDouglas Gregor         }
11295196bc6bSDouglas Gregor 
11305196bc6bSDouglas Gregor         // If there was a clear winner, user it.
11315196bc6bSDouglas Gregor         if (Best.size() == 1) {
11325196bc6bSDouglas Gregor           getDiagnostics().Report(Path[I].second,
11335196bc6bSDouglas Gregor                                   diag::err_no_submodule_suggest)
113469021974SDouglas Gregor             << Path[I].first << Module->getFullModuleName() << Best[0]
11355196bc6bSDouglas Gregor             << SourceRange(Path[0].second, Path[I-1].second)
11365196bc6bSDouglas Gregor             << FixItHint::CreateReplacement(SourceRange(Path[I].second),
11375196bc6bSDouglas Gregor                                             Best[0]);
1138eb90e830SDouglas Gregor 
1139eb90e830SDouglas Gregor           Sub = Module->findSubmodule(Best[0]);
11405196bc6bSDouglas Gregor         }
11415196bc6bSDouglas Gregor       }
11425196bc6bSDouglas Gregor 
1143eb90e830SDouglas Gregor       if (!Sub) {
11445196bc6bSDouglas Gregor         // No submodule by this name. Complain, and don't look for further
11455196bc6bSDouglas Gregor         // submodules.
11465196bc6bSDouglas Gregor         getDiagnostics().Report(Path[I].second, diag::err_no_submodule)
114769021974SDouglas Gregor           << Path[I].first << Module->getFullModuleName()
11485196bc6bSDouglas Gregor           << SourceRange(Path[0].second, Path[I-1].second);
11495196bc6bSDouglas Gregor         break;
11505196bc6bSDouglas Gregor       }
11515196bc6bSDouglas Gregor 
1152eb90e830SDouglas Gregor       Module = Sub;
11535196bc6bSDouglas Gregor     }
11545196bc6bSDouglas Gregor   }
11555196bc6bSDouglas Gregor 
11562537a364SDouglas Gregor   // Make the named module visible, if it's not already part of the module
11572537a364SDouglas Gregor   // we are parsing.
115898a52db8SDouglas Gregor   if (ModuleName != getLangOpts().CurrentModule) {
115998a52db8SDouglas Gregor     if (!Module->IsFromModuleFile) {
116098a52db8SDouglas Gregor       // We have an umbrella header or directory that doesn't actually include
116198a52db8SDouglas Gregor       // all of the headers within the directory it covers. Complain about
116298a52db8SDouglas Gregor       // this missing submodule and recover by forgetting that we ever saw
116398a52db8SDouglas Gregor       // this submodule.
116498a52db8SDouglas Gregor       // FIXME: Should we detect this at module load time? It seems fairly
116598a52db8SDouglas Gregor       // expensive (and rare).
116698a52db8SDouglas Gregor       getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule)
116798a52db8SDouglas Gregor         << Module->getFullModuleName()
116898a52db8SDouglas Gregor         << SourceRange(Path.front().second, Path.back().second);
116998a52db8SDouglas Gregor 
11707a626570SDouglas Gregor       return ModuleLoadResult(0, true);
117198a52db8SDouglas Gregor     }
11721fb5c3a6SDouglas Gregor 
11731fb5c3a6SDouglas Gregor     // Check whether this module is available.
11741fb5c3a6SDouglas Gregor     StringRef Feature;
117589929282SDouglas Gregor     if (!Module->isAvailable(getLangOpts(), getTarget(), Feature)) {
11761fb5c3a6SDouglas Gregor       getDiagnostics().Report(ImportLoc, diag::err_module_unavailable)
11771fb5c3a6SDouglas Gregor         << Module->getFullModuleName()
11781fb5c3a6SDouglas Gregor         << Feature
11791fb5c3a6SDouglas Gregor         << SourceRange(Path.front().second, Path.back().second);
11801fb5c3a6SDouglas Gregor       LastModuleImportLoc = ImportLoc;
11817a626570SDouglas Gregor       LastModuleImportResult = ModuleLoadResult();
11827a626570SDouglas Gregor       return ModuleLoadResult();
11831fb5c3a6SDouglas Gregor     }
11841fb5c3a6SDouglas Gregor 
1185ff2be53fSDouglas Gregor     ModuleManager->makeModuleVisible(Module, Visibility);
118698a52db8SDouglas Gregor   }
11875196bc6bSDouglas Gregor 
1188bcfc7d02SDouglas Gregor   // If this module import was due to an inclusion directive, create an
1189bcfc7d02SDouglas Gregor   // implicit import declaration to capture it in the AST.
1190bcfc7d02SDouglas Gregor   if (IsInclusionDirective && hasASTContext()) {
1191bcfc7d02SDouglas Gregor     TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
119272d1aa3cSArgyrios Kyrtzidis     ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
1193bcfc7d02SDouglas Gregor                                                      ImportLoc, Module,
119472d1aa3cSArgyrios Kyrtzidis                                                      Path.back().second);
119572d1aa3cSArgyrios Kyrtzidis     TU->addDecl(ImportD);
119672d1aa3cSArgyrios Kyrtzidis     if (Consumer)
119772d1aa3cSArgyrios Kyrtzidis       Consumer->HandleImplicitImportDecl(ImportD);
1198bcfc7d02SDouglas Gregor   }
1199bcfc7d02SDouglas Gregor 
12001805b8a4SDouglas Gregor   LastModuleImportLoc = ImportLoc;
12017a626570SDouglas Gregor   LastModuleImportResult = ModuleLoadResult(Module, false);
12027a626570SDouglas Gregor   return LastModuleImportResult;
120308142534SDouglas Gregor }
1204