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"
47527b1c95SDouglas Gregor #include <sys/stat.h>
4837da327cSDouglas Gregor #include <time.h>
4954a88810SDouglas Gregor 
50636404a3SDaniel Dunbar using namespace clang;
51636404a3SDaniel Dunbar 
52e922d9bdSDaniel Dunbar CompilerInstance::CompilerInstance()
535e306b12SDouglas Gregor   : Invocation(new CompilerInvocation()), ModuleManager(0),
54c1bbec85SDouglas Gregor     BuildGlobalModuleIndex(false), ModuleBuildFailed(false) {
55636404a3SDaniel Dunbar }
56636404a3SDaniel Dunbar 
57636404a3SDaniel Dunbar CompilerInstance::~CompilerInstance() {
583c717b45SBenjamin Kramer   assert(OutputFiles.empty() && "Still output files in flight?");
59e922d9bdSDaniel Dunbar }
60e922d9bdSDaniel Dunbar 
6168242254SDaniel Dunbar void CompilerInstance::setInvocation(CompilerInvocation *Value) {
625e14d39aSTed Kremenek   Invocation = Value;
6368242254SDaniel Dunbar }
6468242254SDaniel Dunbar 
65c1bbec85SDouglas Gregor bool CompilerInstance::shouldBuildGlobalModuleIndex() const {
66e060e57bSDouglas Gregor   return (BuildGlobalModuleIndex ||
6711ef0b77SDouglas Gregor           (ModuleManager && ModuleManager->isGlobalIndexUnavailable() &&
6811ef0b77SDouglas Gregor            getFrontendOpts().GenerateGlobalModuleIndex)) &&
69e060e57bSDouglas Gregor          !ModuleBuildFailed;
70c1bbec85SDouglas Gregor }
71c1bbec85SDouglas Gregor 
729c902b55SDavid Blaikie void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) {
737f95d26eSDouglas Gregor   Diagnostics = Value;
74e01dc86dSDaniel Dunbar }
75e01dc86dSDaniel Dunbar 
76e01dc86dSDaniel Dunbar void CompilerInstance::setTarget(TargetInfo *Value) {
775e14d39aSTed Kremenek   Target = Value;
78e01dc86dSDaniel Dunbar }
79e01dc86dSDaniel Dunbar 
80e01dc86dSDaniel Dunbar void CompilerInstance::setFileManager(FileManager *Value) {
815e14d39aSTed Kremenek   FileMgr = Value;
82e01dc86dSDaniel Dunbar }
83e01dc86dSDaniel Dunbar 
84e01dc86dSDaniel Dunbar void CompilerInstance::setSourceManager(SourceManager *Value) {
855e14d39aSTed Kremenek   SourceMgr = Value;
86e01dc86dSDaniel Dunbar }
87e01dc86dSDaniel Dunbar 
885e14d39aSTed Kremenek void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; }
89e01dc86dSDaniel Dunbar 
905e14d39aSTed Kremenek void CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; }
91e01dc86dSDaniel Dunbar 
920e93f017SDouglas Gregor void CompilerInstance::setSema(Sema *S) {
930e93f017SDouglas Gregor   TheSema.reset(S);
940e93f017SDouglas Gregor }
950e93f017SDouglas Gregor 
9656d9c293SDaniel Dunbar void CompilerInstance::setASTConsumer(ASTConsumer *Value) {
9756d9c293SDaniel Dunbar   Consumer.reset(Value);
9856d9c293SDaniel Dunbar }
9956d9c293SDaniel Dunbar 
100e01dc86dSDaniel Dunbar void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
101e01dc86dSDaniel Dunbar   CompletionConsumer.reset(Value);
102e01dc86dSDaniel Dunbar }
103e01dc86dSDaniel Dunbar 
1047d75afc5SDaniel Dunbar // Diagnostics
105811db4eaSDouglas Gregor static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
1067b83306dSDaniel Dunbar                                const CodeGenOptions *CodeGenOpts,
1079c902b55SDavid Blaikie                                DiagnosticsEngine &Diags) {
1082083c32fSDaniel Dunbar   std::string ErrorInfo;
1092083c32fSDaniel Dunbar   bool OwnsStream = false;
1100e62c1ccSChris Lattner   raw_ostream *OS = &llvm::errs();
111811db4eaSDouglas Gregor   if (DiagOpts->DiagnosticLogFile != "-") {
1122083c32fSDaniel Dunbar     // Create the output stream.
1132083c32fSDaniel Dunbar     llvm::raw_fd_ostream *FileOS(
11416125fb6SRafael Espindola         new llvm::raw_fd_ostream(DiagOpts->DiagnosticLogFile.c_str(), ErrorInfo,
11516125fb6SRafael Espindola                                  llvm::sys::fs::F_Append));
1162083c32fSDaniel Dunbar     if (!ErrorInfo.empty()) {
1172083c32fSDaniel Dunbar       Diags.Report(diag::warn_fe_cc_log_diagnostics_failure)
1182118a5cdSSean Silva         << DiagOpts->DiagnosticLogFile << ErrorInfo;
1192083c32fSDaniel Dunbar     } else {
1202083c32fSDaniel Dunbar       FileOS->SetUnbuffered();
1212083c32fSDaniel Dunbar       FileOS->SetUseAtomicWrites(true);
1222083c32fSDaniel Dunbar       OS = FileOS;
1232083c32fSDaniel Dunbar       OwnsStream = true;
1242083c32fSDaniel Dunbar     }
1252083c32fSDaniel Dunbar   }
1262083c32fSDaniel Dunbar 
1272083c32fSDaniel Dunbar   // Chain in the diagnostic client which will log the diagnostics.
1287b83306dSDaniel Dunbar   LogDiagnosticPrinter *Logger = new LogDiagnosticPrinter(*OS, DiagOpts,
1292083c32fSDaniel Dunbar                                                           OwnsStream);
1307b83306dSDaniel Dunbar   if (CodeGenOpts)
1317b83306dSDaniel Dunbar     Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags);
1328b00dcb0SDavid Blaikie   Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger));
1332083c32fSDaniel Dunbar }
1342083c32fSDaniel Dunbar 
135811db4eaSDouglas Gregor static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts,
1364610ea2bSTed Kremenek                                        DiagnosticsEngine &Diags,
1374610ea2bSTed Kremenek                                        StringRef OutputFile) {
1384610ea2bSTed Kremenek   std::string ErrorInfo;
139e2778999SDylan Noblesmith   OwningPtr<llvm::raw_fd_ostream> OS;
1404610ea2bSTed Kremenek   OS.reset(new llvm::raw_fd_ostream(OutputFile.str().c_str(), ErrorInfo,
14116125fb6SRafael Espindola                                     llvm::sys::fs::F_Binary));
1424610ea2bSTed Kremenek 
1434610ea2bSTed Kremenek   if (!ErrorInfo.empty()) {
1444610ea2bSTed Kremenek     Diags.Report(diag::warn_fe_serialized_diag_failure)
1454610ea2bSTed Kremenek       << OutputFile << ErrorInfo;
1464610ea2bSTed Kremenek     return;
1474610ea2bSTed Kremenek   }
1484610ea2bSTed Kremenek 
1494610ea2bSTed Kremenek   DiagnosticConsumer *SerializedConsumer =
1504548e044STed Kremenek     clang::serialized_diags::create(OS.take(), DiagOpts);
1514610ea2bSTed Kremenek 
1524610ea2bSTed Kremenek 
1534610ea2bSTed Kremenek   Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(),
1544610ea2bSTed Kremenek                                                 SerializedConsumer));
1554610ea2bSTed Kremenek }
1564610ea2bSTed Kremenek 
157f1b49e23SSean Silva void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client,
15830071ceaSDouglas Gregor                                          bool ShouldOwnClient) {
159f1b49e23SSean Silva   Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client,
16030071ceaSDouglas Gregor                                   ShouldOwnClient, &getCodeGenOpts());
1617d75afc5SDaniel Dunbar }
1627d75afc5SDaniel Dunbar 
163c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine>
164811db4eaSDouglas Gregor CompilerInstance::createDiagnostics(DiagnosticOptions *Opts,
165e2eefaecSDavid Blaikie                                     DiagnosticConsumer *Client,
1662b9b4642SDouglas Gregor                                     bool ShouldOwnClient,
1677b83306dSDaniel Dunbar                                     const CodeGenOptions *CodeGenOpts) {
168c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
169c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticsEngine>
170811db4eaSDouglas Gregor       Diags(new DiagnosticsEngine(DiagID, Opts));
1711b39a2edSDaniel Dunbar 
1727d75afc5SDaniel Dunbar   // Create the diagnostic client for reporting errors or for
1737d75afc5SDaniel Dunbar   // implementing -verify.
174d0e9e3a6SDouglas Gregor   if (Client) {
175d0e9e3a6SDouglas Gregor     Diags->setClient(Client, ShouldOwnClient);
176d0e9e3a6SDouglas Gregor   } else
1772dd19f1dSDouglas Gregor     Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));
17850ec0da0SDaniel Dunbar 
17950ec0da0SDaniel Dunbar   // Chain in -verify checker, if requested.
180811db4eaSDouglas Gregor   if (Opts->VerifyDiagnostics)
18169609dceSDavid Blaikie     Diags->setClient(new VerifyDiagnosticConsumer(*Diags));
1827d75afc5SDaniel Dunbar 
1832083c32fSDaniel Dunbar   // Chain in -diagnostic-log-file dumper, if requested.
184811db4eaSDouglas Gregor   if (!Opts->DiagnosticLogFile.empty())
1857b83306dSDaniel Dunbar     SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags);
1862083c32fSDaniel Dunbar 
187811db4eaSDouglas Gregor   if (!Opts->DiagnosticSerializationFile.empty())
1884610ea2bSTed Kremenek     SetupSerializedDiagnostics(Opts, *Diags,
189811db4eaSDouglas Gregor                                Opts->DiagnosticSerializationFile);
1904610ea2bSTed Kremenek 
1917d75afc5SDaniel Dunbar   // Configure our handling of diagnostics.
192811db4eaSDouglas Gregor   ProcessWarningOptions(*Diags, *Opts);
1937d75afc5SDaniel Dunbar 
1947f95d26eSDouglas Gregor   return Diags;
1957d75afc5SDaniel Dunbar }
1967d75afc5SDaniel Dunbar 
1977d75afc5SDaniel Dunbar // File Manager
1987d75afc5SDaniel Dunbar 
199546a676aSDaniel Dunbar void CompilerInstance::createFileManager() {
2005e14d39aSTed Kremenek   FileMgr = new FileManager(getFileSystemOpts());
201546a676aSDaniel Dunbar }
202546a676aSDaniel Dunbar 
2037d75afc5SDaniel Dunbar // Source Manager
2047d75afc5SDaniel Dunbar 
2055159f616SChris Lattner void CompilerInstance::createSourceManager(FileManager &FileMgr) {
2065e14d39aSTed Kremenek   SourceMgr = new SourceManager(getDiagnostics(), FileMgr);
207546a676aSDaniel Dunbar }
208aaa148fdSDaniel Dunbar 
2097d75afc5SDaniel Dunbar // Preprocessor
2107d75afc5SDaniel Dunbar 
211aaa148fdSDaniel Dunbar void CompilerInstance::createPreprocessor() {
21208142534SDouglas Gregor   const PreprocessorOptions &PPOpts = getPreprocessorOpts();
213aaa148fdSDaniel Dunbar 
214aaa148fdSDaniel Dunbar   // Create a PTH manager if we are using some form of a token cache.
215aaa148fdSDaniel Dunbar   PTHManager *PTHMgr = 0;
216d6ea9028SDaniel Dunbar   if (!PPOpts.TokenCache.empty())
21708142534SDouglas Gregor     PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics());
218aaa148fdSDaniel Dunbar 
219aaa148fdSDaniel Dunbar   // Create the Preprocessor.
220b85b9ccbSDouglas Gregor   HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(),
2211f76c4e8SManuel Klimek                                               getSourceManager(),
2221fb5c3a6SDouglas Gregor                                               getDiagnostics(),
22389929282SDouglas Gregor                                               getLangOpts(),
22489929282SDouglas Gregor                                               &getTarget());
2251452ff15SDouglas Gregor   PP = new Preprocessor(&getPreprocessorOpts(),
2261452ff15SDouglas Gregor                         getDiagnostics(), getLangOpts(), &getTarget(),
22708142534SDouglas Gregor                         getSourceManager(), *HeaderInfo, *this, PTHMgr,
228aaa148fdSDaniel Dunbar                         /*OwnsHeaderSearch=*/true);
229aaa148fdSDaniel Dunbar 
230aaa148fdSDaniel Dunbar   // Note that this is different then passing PTHMgr to Preprocessor's ctor.
231aaa148fdSDaniel Dunbar   // That argument is used as the IdentifierInfoLookup argument to
232aaa148fdSDaniel Dunbar   // IdentifierTable's ctor.
233aaa148fdSDaniel Dunbar   if (PTHMgr) {
23408142534SDouglas Gregor     PTHMgr->setPreprocessor(&*PP);
235aaa148fdSDaniel Dunbar     PP->setPTHManager(PTHMgr);
236aaa148fdSDaniel Dunbar   }
237aaa148fdSDaniel Dunbar 
2387f6d60dcSDouglas Gregor   if (PPOpts.DetailedRecord)
239f3d587eaSArgyrios Kyrtzidis     PP->createPreprocessingRecord();
2407f6d60dcSDouglas Gregor 
24108142534SDouglas Gregor   InitializePreprocessor(*PP, PPOpts, getHeaderSearchOpts(), getFrontendOpts());
242aaa148fdSDaniel Dunbar 
24317441589SJordan Rose   PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP);
24417441589SJordan Rose 
2451735f4e7SDouglas Gregor   // Set up the module path, including the hash for the
2461735f4e7SDouglas Gregor   // module-creation options.
2472c1dd271SDylan Noblesmith   SmallString<256> SpecificModuleCache(
2481735f4e7SDouglas Gregor                            getHeaderSearchOpts().ModuleCachePath);
2491735f4e7SDouglas Gregor   if (!getHeaderSearchOpts().DisableModuleHash)
2501735f4e7SDouglas Gregor     llvm::sys::path::append(SpecificModuleCache,
2511735f4e7SDouglas Gregor                             getInvocation().getModuleHash());
2522537a364SDouglas Gregor   PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache);
2531735f4e7SDouglas Gregor 
254aaa148fdSDaniel Dunbar   // Handle generating dependencies, if requested.
25508142534SDouglas Gregor   const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
256aaa148fdSDaniel Dunbar   if (!DepOpts.OutputFile.empty())
257aaa148fdSDaniel Dunbar     AttachDependencyFileGen(*PP, DepOpts);
2582e129659SDouglas Gregor   if (!DepOpts.DOTOutputFile.empty())
2592e129659SDouglas Gregor     AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,
26083d46be3SDouglas Gregor                              getHeaderSearchOpts().Sysroot);
26183d46be3SDouglas Gregor 
262aaa148fdSDaniel Dunbar 
26327734fdbSDaniel Dunbar   // Handle generating header include information, if requested.
26427734fdbSDaniel Dunbar   if (DepOpts.ShowHeaderIncludes)
26527734fdbSDaniel Dunbar     AttachHeaderIncludeGen(*PP);
2661af1d275SDaniel Dunbar   if (!DepOpts.HeaderIncludeOutputFile.empty()) {
2670e62c1ccSChris Lattner     StringRef OutputPath = DepOpts.HeaderIncludeOutputFile;
2681af1d275SDaniel Dunbar     if (OutputPath == "-")
2691af1d275SDaniel Dunbar       OutputPath = "";
270fe908a80SDaniel Dunbar     AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath,
271fe908a80SDaniel Dunbar                            /*ShowDepth=*/false);
2720fd6207dSHans Wennborg   }
2730fd6207dSHans Wennborg 
2740fd6207dSHans Wennborg   if (DepOpts.PrintShowIncludes) {
2750fd6207dSHans Wennborg     AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/false, /*OutputPath=*/"",
2760fd6207dSHans Wennborg                            /*ShowDepth=*/true, /*MSStyle=*/true);
2771af1d275SDaniel Dunbar   }
278aaa148fdSDaniel Dunbar }
279df3e30c4SDaniel Dunbar 
280df3e30c4SDaniel Dunbar // ASTContext
281df3e30c4SDaniel Dunbar 
282df3e30c4SDaniel Dunbar void CompilerInstance::createASTContext() {
283df3e30c4SDaniel Dunbar   Preprocessor &PP = getPreprocessor();
2845e14d39aSTed Kremenek   Context = new ASTContext(getLangOpts(), PP.getSourceManager(),
285e8bbc121SDouglas Gregor                            &getTarget(), PP.getIdentifierTable(),
286df3e30c4SDaniel Dunbar                            PP.getSelectorTable(), PP.getBuiltinInfo(),
2875e14d39aSTed Kremenek                            /*size_reserve=*/ 0);
288df3e30c4SDaniel Dunbar }
289599313efSDaniel Dunbar 
290599313efSDaniel Dunbar // ExternalASTSource
291599313efSDaniel Dunbar 
2920e62c1ccSChris Lattner void CompilerInstance::createPCHExternalASTSource(StringRef Path,
29307a89a83SSebastian Redl                                                   bool DisablePCHValidation,
2944a280ff4SArgyrios Kyrtzidis                                                 bool AllowPCHWithCompilerErrors,
29507a89a83SSebastian Redl                                                  void *DeserializationListener){
296e2778999SDylan Noblesmith   OwningPtr<ExternalASTSource> Source;
297009e7f20SSebastian Redl   bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
298599313efSDaniel Dunbar   Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot,
299ce3a8293SDouglas Gregor                                           DisablePCHValidation,
3004a280ff4SArgyrios Kyrtzidis                                           AllowPCHWithCompilerErrors,
30107a89a83SSebastian Redl                                           getPreprocessor(), getASTContext(),
302009e7f20SSebastian Redl                                           DeserializationListener,
303c1bbec85SDouglas Gregor                                           Preamble,
304c1bbec85SDouglas Gregor                                        getFrontendOpts().UseGlobalModuleIndex));
305925296b4SDouglas Gregor   ModuleManager = static_cast<ASTReader*>(Source.get());
306599313efSDaniel Dunbar   getASTContext().setExternalSource(Source);
307599313efSDaniel Dunbar }
308599313efSDaniel Dunbar 
309599313efSDaniel Dunbar ExternalASTSource *
3100e62c1ccSChris Lattner CompilerInstance::createPCHExternalASTSource(StringRef Path,
311599313efSDaniel Dunbar                                              const std::string &Sysroot,
312ce3a8293SDouglas Gregor                                              bool DisablePCHValidation,
3134a280ff4SArgyrios Kyrtzidis                                              bool AllowPCHWithCompilerErrors,
314599313efSDaniel Dunbar                                              Preprocessor &PP,
31507a89a83SSebastian Redl                                              ASTContext &Context,
316009e7f20SSebastian Redl                                              void *DeserializationListener,
317c1bbec85SDouglas Gregor                                              bool Preamble,
318c1bbec85SDouglas Gregor                                              bool UseGlobalModuleIndex) {
319e2778999SDylan Noblesmith   OwningPtr<ASTReader> Reader;
3208835e03cSDouglas Gregor   Reader.reset(new ASTReader(PP, Context,
321c567ba26SDouglas Gregor                              Sysroot.empty() ? "" : Sysroot.c_str(),
322d7c16b25SArgyrios Kyrtzidis                              DisablePCHValidation,
323c1bbec85SDouglas Gregor                              AllowPCHWithCompilerErrors,
324c1bbec85SDouglas Gregor                              UseGlobalModuleIndex));
325599313efSDaniel Dunbar 
32607a89a83SSebastian Redl   Reader->setDeserializationListener(
3273e31c724SSebastian Redl             static_cast<ASTDeserializationListener *>(DeserializationListener));
328009e7f20SSebastian Redl   switch (Reader->ReadAST(Path,
329a6895d8aSDouglas Gregor                           Preamble ? serialization::MK_Preamble
3304b29c16eSDouglas Gregor                                    : serialization::MK_PCH,
3312ec29367SArgyrios Kyrtzidis                           SourceLocation(),
3324b29c16eSDouglas Gregor                           ASTReader::ARR_None)) {
3332c499f65SSebastian Redl   case ASTReader::Success:
334599313efSDaniel Dunbar     // Set the predefines buffer as suggested by the PCH reader. Typically, the
335599313efSDaniel Dunbar     // predefines buffer will be empty.
336599313efSDaniel Dunbar     PP.setPredefines(Reader->getSuggestedPredefines());
337599313efSDaniel Dunbar     return Reader.take();
338599313efSDaniel Dunbar 
3392c499f65SSebastian Redl   case ASTReader::Failure:
340599313efSDaniel Dunbar     // Unrecoverable failure: don't even try to process the input file.
341599313efSDaniel Dunbar     break;
342599313efSDaniel Dunbar 
3437029ce1aSDouglas Gregor   case ASTReader::Missing:
344c9ad5fb6SDouglas Gregor   case ASTReader::OutOfDate:
345c9ad5fb6SDouglas Gregor   case ASTReader::VersionMismatch:
346c9ad5fb6SDouglas Gregor   case ASTReader::ConfigurationMismatch:
347c9ad5fb6SDouglas Gregor   case ASTReader::HadErrors:
348599313efSDaniel Dunbar     // No suitable PCH file could be found. Return an error.
349599313efSDaniel Dunbar     break;
350599313efSDaniel Dunbar   }
351599313efSDaniel Dunbar 
352599313efSDaniel Dunbar   return 0;
353599313efSDaniel Dunbar }
354f7093b5aSDaniel Dunbar 
355f7093b5aSDaniel Dunbar // Code Completion
356f7093b5aSDaniel Dunbar 
3578e984da8SDouglas Gregor static bool EnableCodeCompletion(Preprocessor &PP,
3588e984da8SDouglas Gregor                                  const std::string &Filename,
3598e984da8SDouglas Gregor                                  unsigned Line,
3608e984da8SDouglas Gregor                                  unsigned Column) {
3618e984da8SDouglas Gregor   // Tell the source manager to chop off the given file at a specific
3628e984da8SDouglas Gregor   // line and column.
3635159f616SChris Lattner   const FileEntry *Entry = PP.getFileManager().getFile(Filename);
3648e984da8SDouglas Gregor   if (!Entry) {
3658e984da8SDouglas Gregor     PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
3668e984da8SDouglas Gregor       << Filename;
3678e984da8SDouglas Gregor     return true;
3688e984da8SDouglas Gregor   }
3698e984da8SDouglas Gregor 
3708e984da8SDouglas Gregor   // Truncate the named file at the given line/column.
3718e984da8SDouglas Gregor   PP.SetCodeCompletionPoint(Entry, Line, Column);
3728e984da8SDouglas Gregor   return false;
3738e984da8SDouglas Gregor }
3748e984da8SDouglas Gregor 
375f7093b5aSDaniel Dunbar void CompilerInstance::createCodeCompletionConsumer() {
376f7093b5aSDaniel Dunbar   const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt;
3778e984da8SDouglas Gregor   if (!CompletionConsumer) {
3782fca3c2cSErik Verbruggen     setCodeCompletionConsumer(
379f7093b5aSDaniel Dunbar       createCodeCompletionConsumer(getPreprocessor(),
380f7093b5aSDaniel Dunbar                                    Loc.FileName, Loc.Line, Loc.Column,
3813292d06aSDmitri Gribenko                                    getFrontendOpts().CodeCompleteOpts,
382f7093b5aSDaniel Dunbar                                    llvm::outs()));
38300a0cf70SDouglas Gregor     if (!CompletionConsumer)
38400a0cf70SDouglas Gregor       return;
3858e984da8SDouglas Gregor   } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName,
3868e984da8SDouglas Gregor                                   Loc.Line, Loc.Column)) {
3872fca3c2cSErik Verbruggen     setCodeCompletionConsumer(0);
3888e984da8SDouglas Gregor     return;
3898e984da8SDouglas Gregor   }
390f09935f1SDouglas Gregor 
391f09935f1SDouglas Gregor   if (CompletionConsumer->isOutputBinary() &&
392a3346d87SRafael Espindola       llvm::sys::ChangeStdoutToBinary()) {
393f09935f1SDouglas Gregor     getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary);
3942fca3c2cSErik Verbruggen     setCodeCompletionConsumer(0);
395f09935f1SDouglas Gregor   }
396f7093b5aSDaniel Dunbar }
397f7093b5aSDaniel Dunbar 
3985505dff8SKovarththanan Rajaratnam void CompilerInstance::createFrontendTimer() {
3995505dff8SKovarththanan Rajaratnam   FrontendTimer.reset(new llvm::Timer("Clang front-end timer"));
4005505dff8SKovarththanan Rajaratnam }
4015505dff8SKovarththanan Rajaratnam 
402f7093b5aSDaniel Dunbar CodeCompleteConsumer *
403f7093b5aSDaniel Dunbar CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP,
404f7093b5aSDaniel Dunbar                                                const std::string &Filename,
405f7093b5aSDaniel Dunbar                                                unsigned Line,
406f7093b5aSDaniel Dunbar                                                unsigned Column,
4073292d06aSDmitri Gribenko                                                const CodeCompleteOptions &Opts,
4080e62c1ccSChris Lattner                                                raw_ostream &OS) {
4098e984da8SDouglas Gregor   if (EnableCodeCompletion(PP, Filename, Line, Column))
410f7093b5aSDaniel Dunbar     return 0;
411f7093b5aSDaniel Dunbar 
412f7093b5aSDaniel Dunbar   // Set up the creation routine for code-completion.
4133292d06aSDmitri Gribenko   return new PrintingCodeCompleteConsumer(Opts, OS);
414f7093b5aSDaniel Dunbar }
415566eeb2dSDaniel Dunbar 
41669f74f80SDouglas Gregor void CompilerInstance::createSema(TranslationUnitKind TUKind,
4170e93f017SDouglas Gregor                                   CodeCompleteConsumer *CompletionConsumer) {
4180e93f017SDouglas Gregor   TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(),
41969f74f80SDouglas Gregor                          TUKind, CompletionConsumer));
4200e93f017SDouglas Gregor }
4210e93f017SDouglas Gregor 
422566eeb2dSDaniel Dunbar // Output Files
423566eeb2dSDaniel Dunbar 
424d0599970SArgyrios Kyrtzidis void CompilerInstance::addOutputFile(const OutputFile &OutFile) {
425d0599970SArgyrios Kyrtzidis   assert(OutFile.OS && "Attempt to add empty stream to output list!");
426d0599970SArgyrios Kyrtzidis   OutputFiles.push_back(OutFile);
427566eeb2dSDaniel Dunbar }
428566eeb2dSDaniel Dunbar 
4291c558cd7SKovarththanan Rajaratnam void CompilerInstance::clearOutputFiles(bool EraseFiles) {
430d0599970SArgyrios Kyrtzidis   for (std::list<OutputFile>::iterator
431566eeb2dSDaniel Dunbar          it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) {
432d0599970SArgyrios Kyrtzidis     delete it->OS;
433d0599970SArgyrios Kyrtzidis     if (!it->TempFilename.empty()) {
434b5c356a4SAnders Carlsson       if (EraseFiles) {
435b5c356a4SAnders Carlsson         bool existed;
436b5c356a4SAnders Carlsson         llvm::sys::fs::remove(it->TempFilename, existed);
437b5c356a4SAnders Carlsson       } else {
4382c1dd271SDylan Noblesmith         SmallString<128> NewOutFile(it->Filename);
439b5c356a4SAnders Carlsson 
44071731d6bSArgyrios Kyrtzidis         // If '-working-directory' was passed, the output filename should be
44171731d6bSArgyrios Kyrtzidis         // relative to that.
4429ba8fb1eSAnders Carlsson         FileMgr->FixupRelativePath(NewOutFile);
443b5c356a4SAnders Carlsson         if (llvm::error_code ec = llvm::sys::fs::rename(it->TempFilename,
444b5c356a4SAnders Carlsson                                                         NewOutFile.str())) {
4453ef9c447SManuel Klimek           getDiagnostics().Report(diag::err_unable_to_rename_temp)
446b5c356a4SAnders Carlsson             << it->TempFilename << it->Filename << ec.message();
447b5c356a4SAnders Carlsson 
448b5c356a4SAnders Carlsson           bool existed;
449b5c356a4SAnders Carlsson           llvm::sys::fs::remove(it->TempFilename, existed);
450d0599970SArgyrios Kyrtzidis         }
451d0599970SArgyrios Kyrtzidis       }
452d0599970SArgyrios Kyrtzidis     } else if (!it->Filename.empty() && EraseFiles)
453399ab33aSRafael Espindola       llvm::sys::fs::remove(it->Filename);
454d0599970SArgyrios Kyrtzidis 
455566eeb2dSDaniel Dunbar   }
456566eeb2dSDaniel Dunbar   OutputFiles.clear();
457566eeb2dSDaniel Dunbar }
458566eeb2dSDaniel Dunbar 
459420b0f1bSDaniel Dunbar llvm::raw_fd_ostream *
460420b0f1bSDaniel Dunbar CompilerInstance::createDefaultOutputFile(bool Binary,
4610e62c1ccSChris Lattner                                           StringRef InFile,
4620e62c1ccSChris Lattner                                           StringRef Extension) {
463420b0f1bSDaniel Dunbar   return createOutputFile(getFrontendOpts().OutputFile, Binary,
464ae77b3dfSDaniel Dunbar                           /*RemoveFileOnSignal=*/true, InFile, Extension,
465ae77b3dfSDaniel Dunbar                           /*UseTemporary=*/true);
466420b0f1bSDaniel Dunbar }
467420b0f1bSDaniel Dunbar 
468420b0f1bSDaniel Dunbar llvm::raw_fd_ostream *
4690e62c1ccSChris Lattner CompilerInstance::createOutputFile(StringRef OutputPath,
470e326f9bbSDaniel Dunbar                                    bool Binary, bool RemoveFileOnSignal,
4710e62c1ccSChris Lattner                                    StringRef InFile,
47208a2bfd2SArgyrios Kyrtzidis                                    StringRef Extension,
473b9c62c07SDaniel Dunbar                                    bool UseTemporary,
474b9c62c07SDaniel Dunbar                                    bool CreateMissingDirectories) {
475d0599970SArgyrios Kyrtzidis   std::string Error, OutputPathName, TempPathName;
476420b0f1bSDaniel Dunbar   llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary,
477e326f9bbSDaniel Dunbar                                               RemoveFileOnSignal,
478420b0f1bSDaniel Dunbar                                               InFile, Extension,
47908a2bfd2SArgyrios Kyrtzidis                                               UseTemporary,
480b9c62c07SDaniel Dunbar                                               CreateMissingDirectories,
481d0599970SArgyrios Kyrtzidis                                               &OutputPathName,
482d0599970SArgyrios Kyrtzidis                                               &TempPathName);
483420b0f1bSDaniel Dunbar   if (!OS) {
4847554699aSDaniel Dunbar     getDiagnostics().Report(diag::err_fe_unable_to_open_output)
4857554699aSDaniel Dunbar       << OutputPath << Error;
4867554699aSDaniel Dunbar     return 0;
487420b0f1bSDaniel Dunbar   }
488420b0f1bSDaniel Dunbar 
489420b0f1bSDaniel Dunbar   // Add the output file -- but don't try to remove "-", since this means we are
490420b0f1bSDaniel Dunbar   // using stdin.
491d0599970SArgyrios Kyrtzidis   addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "",
492d0599970SArgyrios Kyrtzidis                 TempPathName, OS));
493420b0f1bSDaniel Dunbar 
494420b0f1bSDaniel Dunbar   return OS;
495420b0f1bSDaniel Dunbar }
496420b0f1bSDaniel Dunbar 
497420b0f1bSDaniel Dunbar llvm::raw_fd_ostream *
4980e62c1ccSChris Lattner CompilerInstance::createOutputFile(StringRef OutputPath,
499420b0f1bSDaniel Dunbar                                    std::string &Error,
500420b0f1bSDaniel Dunbar                                    bool Binary,
501e326f9bbSDaniel Dunbar                                    bool RemoveFileOnSignal,
5020e62c1ccSChris Lattner                                    StringRef InFile,
5030e62c1ccSChris Lattner                                    StringRef Extension,
50408a2bfd2SArgyrios Kyrtzidis                                    bool UseTemporary,
505b9c62c07SDaniel Dunbar                                    bool CreateMissingDirectories,
506d0599970SArgyrios Kyrtzidis                                    std::string *ResultPathName,
507d0599970SArgyrios Kyrtzidis                                    std::string *TempPathName) {
508b9c62c07SDaniel Dunbar   assert((!CreateMissingDirectories || UseTemporary) &&
509b9c62c07SDaniel Dunbar          "CreateMissingDirectories is only allowed when using temporary files");
510b9c62c07SDaniel Dunbar 
511d0599970SArgyrios Kyrtzidis   std::string OutFile, TempFile;
512420b0f1bSDaniel Dunbar   if (!OutputPath.empty()) {
513420b0f1bSDaniel Dunbar     OutFile = OutputPath;
514420b0f1bSDaniel Dunbar   } else if (InFile == "-") {
515420b0f1bSDaniel Dunbar     OutFile = "-";
516420b0f1bSDaniel Dunbar   } else if (!Extension.empty()) {
517399ab33aSRafael Espindola     SmallString<128> Path(InFile);
518399ab33aSRafael Espindola     llvm::sys::path::replace_extension(Path, Extension);
519420b0f1bSDaniel Dunbar     OutFile = Path.str();
520420b0f1bSDaniel Dunbar   } else {
521420b0f1bSDaniel Dunbar     OutFile = "-";
522420b0f1bSDaniel Dunbar   }
523420b0f1bSDaniel Dunbar 
524e2778999SDylan Noblesmith   OwningPtr<llvm::raw_fd_ostream> OS;
52508a2bfd2SArgyrios Kyrtzidis   std::string OSFile;
52608a2bfd2SArgyrios Kyrtzidis 
52773c23a71SRafael Espindola   if (UseTemporary) {
52873c23a71SRafael Espindola     if (OutFile == "-")
52973c23a71SRafael Espindola       UseTemporary = false;
53073c23a71SRafael Espindola     else {
53173c23a71SRafael Espindola       llvm::sys::fs::file_status Status;
53273c23a71SRafael Espindola       llvm::sys::fs::status(OutputPath, Status);
53373c23a71SRafael Espindola       if (llvm::sys::fs::exists(Status)) {
53473c23a71SRafael Espindola         // Fail early if we can't write to the final destination.
53573c23a71SRafael Espindola         if (!llvm::sys::fs::can_write(OutputPath))
53673c23a71SRafael Espindola           return 0;
53773c23a71SRafael Espindola 
53873c23a71SRafael Espindola         // Don't use a temporary if the output is a special file. This handles
53973c23a71SRafael Espindola         // things like '-o /dev/null'
54073c23a71SRafael Espindola         if (!llvm::sys::fs::is_regular_file(Status))
54173c23a71SRafael Espindola           UseTemporary = false;
54273c23a71SRafael Espindola       }
54373c23a71SRafael Espindola     }
54473c23a71SRafael Espindola   }
54573c23a71SRafael Espindola 
54673c23a71SRafael Espindola   if (UseTemporary) {
547d0599970SArgyrios Kyrtzidis     // Create a temporary file.
5482c1dd271SDylan Noblesmith     SmallString<128> TempPath;
54908a2bfd2SArgyrios Kyrtzidis     TempPath = OutFile;
55008a2bfd2SArgyrios Kyrtzidis     TempPath += "-%%%%%%%%";
55108a2bfd2SArgyrios Kyrtzidis     int fd;
55218627115SRafael Espindola     llvm::error_code EC =
55318627115SRafael Espindola         llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath);
554157f34bdSRafael Espindola 
555157f34bdSRafael Espindola     if (CreateMissingDirectories &&
5561d0912a4SRafael Espindola         EC == llvm::errc::no_such_file_or_directory) {
557157f34bdSRafael Espindola       StringRef Parent = llvm::sys::path::parent_path(OutputPath);
558157f34bdSRafael Espindola       EC = llvm::sys::fs::create_directories(Parent);
559157f34bdSRafael Espindola       if (!EC) {
56018627115SRafael Espindola         EC = llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath);
561157f34bdSRafael Espindola       }
562157f34bdSRafael Espindola     }
563157f34bdSRafael Espindola 
564157f34bdSRafael Espindola     if (!EC) {
56508a2bfd2SArgyrios Kyrtzidis       OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true));
56608a2bfd2SArgyrios Kyrtzidis       OSFile = TempFile = TempPath.str();
56708a2bfd2SArgyrios Kyrtzidis     }
56873c23a71SRafael Espindola     // If we failed to create the temporary, fallback to writing to the file
56973c23a71SRafael Espindola     // directly. This handles the corner case where we cannot write to the
57073c23a71SRafael Espindola     // directory, but can write to the file.
571d0599970SArgyrios Kyrtzidis   }
572d0599970SArgyrios Kyrtzidis 
57308a2bfd2SArgyrios Kyrtzidis   if (!OS) {
57408a2bfd2SArgyrios Kyrtzidis     OSFile = OutFile;
57516125fb6SRafael Espindola     OS.reset(new llvm::raw_fd_ostream(
57616125fb6SRafael Espindola         OSFile.c_str(), Error,
57716125fb6SRafael Espindola         (Binary ? llvm::sys::fs::F_Binary : llvm::sys::fs::F_None)));
5782eaef18eSDaniel Dunbar     if (!Error.empty())
579420b0f1bSDaniel Dunbar       return 0;
58008a2bfd2SArgyrios Kyrtzidis   }
581420b0f1bSDaniel Dunbar 
582d0599970SArgyrios Kyrtzidis   // Make sure the out stream file gets removed if we crash.
583e326f9bbSDaniel Dunbar   if (RemoveFileOnSignal)
58418556de3SRafael Espindola     llvm::sys::RemoveFileOnSignal(OSFile);
585d0599970SArgyrios Kyrtzidis 
586420b0f1bSDaniel Dunbar   if (ResultPathName)
587420b0f1bSDaniel Dunbar     *ResultPathName = OutFile;
588d0599970SArgyrios Kyrtzidis   if (TempPathName)
589d0599970SArgyrios Kyrtzidis     *TempPathName = TempFile;
590420b0f1bSDaniel Dunbar 
5912eaef18eSDaniel Dunbar   return OS.take();
592420b0f1bSDaniel Dunbar }
593409e890fSDaniel Dunbar 
594409e890fSDaniel Dunbar // Initialization Utilities
595409e890fSDaniel Dunbar 
5961b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){
5971b3240b0SArgyrios Kyrtzidis   return InitializeSourceManager(Input, getDiagnostics(),
598a686e1b0SDouglas Gregor                                  getFileManager(), getSourceManager(),
599a686e1b0SDouglas Gregor                                  getFrontendOpts());
600409e890fSDaniel Dunbar }
601409e890fSDaniel Dunbar 
6021b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input,
6039c902b55SDavid Blaikie                                                DiagnosticsEngine &Diags,
604409e890fSDaniel Dunbar                                                FileManager &FileMgr,
605409e890fSDaniel Dunbar                                                SourceManager &SourceMgr,
606409e890fSDaniel Dunbar                                                const FrontendOptions &Opts) {
6071b3240b0SArgyrios Kyrtzidis   SrcMgr::CharacteristicKind
608873c8583SArgyrios Kyrtzidis     Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
6091b3240b0SArgyrios Kyrtzidis 
6106566e23eSArgyrios Kyrtzidis   if (Input.isBuffer()) {
6116566e23eSArgyrios Kyrtzidis     SourceMgr.createMainFileIDForMemBuffer(Input.getBuffer(), Kind);
6126566e23eSArgyrios Kyrtzidis     assert(!SourceMgr.getMainFileID().isInvalid() &&
6136566e23eSArgyrios Kyrtzidis            "Couldn't establish MainFileID!");
6146566e23eSArgyrios Kyrtzidis     return true;
6156566e23eSArgyrios Kyrtzidis   }
6166566e23eSArgyrios Kyrtzidis 
6176566e23eSArgyrios Kyrtzidis   StringRef InputFile = Input.getFile();
6186566e23eSArgyrios Kyrtzidis 
6197c06d866SArgyrios Kyrtzidis   // Figure out where to get and map in the main file.
6207c06d866SArgyrios Kyrtzidis   if (InputFile != "-") {
6213841fa38SBenjamin Kramer     const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true);
62252765215SDan Gohman     if (!File) {
623409e890fSDaniel Dunbar       Diags.Report(diag::err_fe_error_reading) << InputFile;
624409e890fSDaniel Dunbar       return false;
625409e890fSDaniel Dunbar     }
626e2951f48SDaniel Dunbar 
627e2951f48SDaniel Dunbar     // The natural SourceManager infrastructure can't currently handle named
628e2951f48SDaniel Dunbar     // pipes, but we would at least like to accept them for the main
6293841fa38SBenjamin Kramer     // file. Detect them here, read them with the volatile flag so FileMgr will
6303841fa38SBenjamin Kramer     // pick up the correct size, and simply override their contents as we do for
6313841fa38SBenjamin Kramer     // STDIN.
632e2951f48SDaniel Dunbar     if (File->isNamedPipe()) {
6333841fa38SBenjamin Kramer       std::string ErrorStr;
6343841fa38SBenjamin Kramer       if (llvm::MemoryBuffer *MB =
6353841fa38SBenjamin Kramer               FileMgr.getBufferForFile(File, &ErrorStr, /*isVolatile=*/true)) {
636db0745abSDaniel Dunbar         // Create a new virtual file that will have the correct size.
637db0745abSDaniel Dunbar         File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0);
6383841fa38SBenjamin Kramer         SourceMgr.overrideFileContents(File, MB);
6393841fa38SBenjamin Kramer       } else {
6403841fa38SBenjamin Kramer         Diags.Report(diag::err_cannot_open_file) << InputFile << ErrorStr;
6413841fa38SBenjamin Kramer         return false;
6423841fa38SBenjamin Kramer       }
643e2951f48SDaniel Dunbar     }
644db0745abSDaniel Dunbar 
645db0745abSDaniel Dunbar     SourceMgr.createMainFileID(File, Kind);
646409e890fSDaniel Dunbar   } else {
647e2778999SDylan Noblesmith     OwningPtr<llvm::MemoryBuffer> SB;
6483841fa38SBenjamin Kramer     if (llvm::error_code ec = llvm::MemoryBuffer::getSTDIN(SB)) {
6493841fa38SBenjamin Kramer       Diags.Report(diag::err_fe_error_reading_stdin) << ec.message();
650409e890fSDaniel Dunbar       return false;
651409e890fSDaniel Dunbar     }
6522f76cd75SDan Gohman     const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(),
6535159f616SChris Lattner                                                    SB->getBufferSize(), 0);
654a686e1b0SDouglas Gregor     SourceMgr.createMainFileID(File, Kind);
655d9da7a1fSMichael J. Spencer     SourceMgr.overrideFileContents(File, SB.take());
656409e890fSDaniel Dunbar   }
657409e890fSDaniel Dunbar 
65852765215SDan Gohman   assert(!SourceMgr.getMainFileID().isInvalid() &&
65952765215SDan Gohman          "Couldn't establish MainFileID!");
660409e890fSDaniel Dunbar   return true;
661409e890fSDaniel Dunbar }
6624f2bc55dSDaniel Dunbar 
6634f2bc55dSDaniel Dunbar // High-Level Operations
6644f2bc55dSDaniel Dunbar 
6654f2bc55dSDaniel Dunbar bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
6664f2bc55dSDaniel Dunbar   assert(hasDiagnostics() && "Diagnostics engine is not initialized!");
6674f2bc55dSDaniel Dunbar   assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!");
6684f2bc55dSDaniel Dunbar   assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!");
6694f2bc55dSDaniel Dunbar 
6704f2bc55dSDaniel Dunbar   // FIXME: Take this as an argument, once all the APIs we used have moved to
6714f2bc55dSDaniel Dunbar   // taking it as an input instead of hard-coding llvm::errs.
6720e62c1ccSChris Lattner   raw_ostream &OS = llvm::errs();
6734f2bc55dSDaniel Dunbar 
6744f2bc55dSDaniel Dunbar   // Create the target instance.
675f8715de5SDouglas Gregor   setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), &getTargetOpts()));
6764f2bc55dSDaniel Dunbar   if (!hasTarget())
6774f2bc55dSDaniel Dunbar     return false;
6784f2bc55dSDaniel Dunbar 
6794f2bc55dSDaniel Dunbar   // Inform the target of the language options.
6804f2bc55dSDaniel Dunbar   //
6814f2bc55dSDaniel Dunbar   // FIXME: We shouldn't need to do this, the target should be immutable once
6824f2bc55dSDaniel Dunbar   // created. This complexity should be lifted elsewhere.
6834f2bc55dSDaniel Dunbar   getTarget().setForcedLangOptions(getLangOpts());
6844f2bc55dSDaniel Dunbar 
68529898f45SFariborz Jahanian   // rewriter project will change target built-in bool type from its default.
68629898f45SFariborz Jahanian   if (getFrontendOpts().ProgramAction == frontend::RewriteObjC)
68729898f45SFariborz Jahanian     getTarget().noSignedCharForObjCBool();
68829898f45SFariborz Jahanian 
6894f2bc55dSDaniel Dunbar   // Validate/process some options.
6904f2bc55dSDaniel Dunbar   if (getHeaderSearchOpts().Verbose)
6914f2bc55dSDaniel Dunbar     OS << "clang -cc1 version " CLANG_VERSION_STRING
6924f2bc55dSDaniel Dunbar        << " based upon " << PACKAGE_STRING
6938188c8a1SSebastian Pop        << " default target " << llvm::sys::getDefaultTargetTriple() << "\n";
6944f2bc55dSDaniel Dunbar 
6954f2bc55dSDaniel Dunbar   if (getFrontendOpts().ShowTimers)
6964f2bc55dSDaniel Dunbar     createFrontendTimer();
6974f2bc55dSDaniel Dunbar 
698171b780cSDouglas Gregor   if (getFrontendOpts().ShowStats)
699171b780cSDouglas Gregor     llvm::EnableStatistics();
700171b780cSDouglas Gregor 
7014f2bc55dSDaniel Dunbar   for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) {
7024f2bc55dSDaniel Dunbar     // Reset the ID tables if we are reusing the SourceManager.
703aed46fcbSDaniel Dunbar     if (hasSourceManager())
7044f2bc55dSDaniel Dunbar       getSourceManager().clearIDTables();
7054f2bc55dSDaniel Dunbar 
70632fbe312SDouglas Gregor     if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) {
7074f2bc55dSDaniel Dunbar       Act.Execute();
7084f2bc55dSDaniel Dunbar       Act.EndSourceFile();
7094f2bc55dSDaniel Dunbar     }
7104f2bc55dSDaniel Dunbar   }
7114f2bc55dSDaniel Dunbar 
7127910d7b7SArgyrios Kyrtzidis   // Notify the diagnostic client that all files were processed.
7137910d7b7SArgyrios Kyrtzidis   getDiagnostics().getClient()->finish();
7147910d7b7SArgyrios Kyrtzidis 
715198cb4dfSChris Lattner   if (getDiagnosticOpts().ShowCarets) {
716c79346a5SArgyrios Kyrtzidis     // We can have multiple diagnostics sharing one diagnostic client.
717c79346a5SArgyrios Kyrtzidis     // Get the total number of warnings/errors from the client.
718c79346a5SArgyrios Kyrtzidis     unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings();
719c79346a5SArgyrios Kyrtzidis     unsigned NumErrors = getDiagnostics().getClient()->getNumErrors();
720198cb4dfSChris Lattner 
721198cb4dfSChris Lattner     if (NumWarnings)
722198cb4dfSChris Lattner       OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s");
723198cb4dfSChris Lattner     if (NumWarnings && NumErrors)
724198cb4dfSChris Lattner       OS << " and ";
725198cb4dfSChris Lattner     if (NumErrors)
726198cb4dfSChris Lattner       OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s");
727198cb4dfSChris Lattner     if (NumWarnings || NumErrors)
728198cb4dfSChris Lattner       OS << " generated.\n";
729198cb4dfSChris Lattner   }
7304f2bc55dSDaniel Dunbar 
731aed46fcbSDaniel Dunbar   if (getFrontendOpts().ShowStats && hasFileManager()) {
7324f2bc55dSDaniel Dunbar     getFileManager().PrintStats();
7334f2bc55dSDaniel Dunbar     OS << "\n";
7344f2bc55dSDaniel Dunbar   }
7354f2bc55dSDaniel Dunbar 
736bc467933SArgyrios Kyrtzidis   return !getDiagnostics().getClient()->getNumErrors();
7374f2bc55dSDaniel Dunbar }
7384f2bc55dSDaniel Dunbar 
739faeb1d46SDouglas Gregor /// \brief Determine the appropriate source input kind based on language
740faeb1d46SDouglas Gregor /// options.
741faeb1d46SDouglas Gregor static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) {
742faeb1d46SDouglas Gregor   if (LangOpts.OpenCL)
743faeb1d46SDouglas Gregor     return IK_OpenCL;
744faeb1d46SDouglas Gregor   if (LangOpts.CUDA)
745faeb1d46SDouglas Gregor     return IK_CUDA;
746faeb1d46SDouglas Gregor   if (LangOpts.ObjC1)
747faeb1d46SDouglas Gregor     return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC;
748faeb1d46SDouglas Gregor   return LangOpts.CPlusPlus? IK_CXX : IK_C;
749faeb1d46SDouglas Gregor }
750faeb1d46SDouglas Gregor 
75151e0b541SDouglas Gregor namespace {
752514b636aSDouglas Gregor   struct CompileModuleMapData {
753514b636aSDouglas Gregor     CompilerInstance &Instance;
754514b636aSDouglas Gregor     GenerateModuleAction &CreateModuleAction;
755514b636aSDouglas Gregor   };
756514b636aSDouglas Gregor }
757514b636aSDouglas Gregor 
758514b636aSDouglas Gregor /// \brief Helper function that executes the module-generating action under
759514b636aSDouglas Gregor /// a crash recovery context.
760514b636aSDouglas Gregor static void doCompileMapModule(void *UserData) {
761514b636aSDouglas Gregor   CompileModuleMapData &Data
762514b636aSDouglas Gregor     = *reinterpret_cast<CompileModuleMapData *>(UserData);
763514b636aSDouglas Gregor   Data.Instance.ExecuteAction(Data.CreateModuleAction);
764514b636aSDouglas Gregor }
765514b636aSDouglas Gregor 
7665dc3899cSDouglas Gregor namespace {
7675dc3899cSDouglas Gregor   /// \brief Function object that checks with the given macro definition should
7685dc3899cSDouglas Gregor   /// be removed, because it is one of the ignored macros.
7695dc3899cSDouglas Gregor   class RemoveIgnoredMacro {
7705dc3899cSDouglas Gregor     const HeaderSearchOptions &HSOpts;
7715dc3899cSDouglas Gregor 
7725dc3899cSDouglas Gregor   public:
7735dc3899cSDouglas Gregor     explicit RemoveIgnoredMacro(const HeaderSearchOptions &HSOpts)
7745dc3899cSDouglas Gregor       : HSOpts(HSOpts) { }
7755dc3899cSDouglas Gregor 
7765dc3899cSDouglas Gregor     bool operator()(const std::pair<std::string, bool> &def) const {
7772236c20fSDouglas Gregor       StringRef MacroDef = def.first;
7782236c20fSDouglas Gregor       return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0;
7795dc3899cSDouglas Gregor     }
7805dc3899cSDouglas Gregor   };
7815dc3899cSDouglas Gregor }
7825dc3899cSDouglas Gregor 
783514b636aSDouglas Gregor /// \brief Compile a module file for the given module, using the options
784514b636aSDouglas Gregor /// provided by the importing compiler instance.
785faeb1d46SDouglas Gregor static void compileModule(CompilerInstance &ImportingInstance,
786af8f0263SDouglas Gregor                           SourceLocation ImportLoc,
787de3ef502SDouglas Gregor                           Module *Module,
7886dc57927SDouglas Gregor                           StringRef ModuleFileName) {
789157f34bdSRafael Espindola   // FIXME: have LockFileManager return an error_code so that we can
790157f34bdSRafael Espindola   // avoid the mkdir when the directory already exists.
791157f34bdSRafael Espindola   StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
792157f34bdSRafael Espindola   llvm::sys::fs::create_directories(Dir);
793157f34bdSRafael Espindola 
794e212489fSDouglas Gregor   llvm::LockFileManager Locked(ModuleFileName);
79554a88810SDouglas Gregor   switch (Locked) {
796e212489fSDouglas Gregor   case llvm::LockFileManager::LFS_Error:
79754a88810SDouglas Gregor     return;
79854a88810SDouglas Gregor 
799e212489fSDouglas Gregor   case llvm::LockFileManager::LFS_Owned:
80054a88810SDouglas Gregor     // We're responsible for building the module ourselves. Do so below.
80154a88810SDouglas Gregor     break;
80254a88810SDouglas Gregor 
803e212489fSDouglas Gregor   case llvm::LockFileManager::LFS_Shared:
80454a88810SDouglas Gregor     // Someone else is responsible for building the module. Wait for them to
80554a88810SDouglas Gregor     // finish.
80654a88810SDouglas Gregor     Locked.waitForUnlock();
807188dbef2SDouglas Gregor     return;
80854a88810SDouglas Gregor   }
80954a88810SDouglas Gregor 
810514b636aSDouglas Gregor   ModuleMap &ModMap
811514b636aSDouglas Gregor     = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
812514b636aSDouglas Gregor 
813faeb1d46SDouglas Gregor   // Construct a compiler invocation for creating this module.
814c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<CompilerInvocation> Invocation
815faeb1d46SDouglas Gregor     (new CompilerInvocation(ImportingInstance.getInvocation()));
81644bf68d8SDouglas Gregor 
817f545f67dSDouglas Gregor   PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
818f545f67dSDouglas Gregor 
81944bf68d8SDouglas Gregor   // For any options that aren't intended to affect how a module is built,
82044bf68d8SDouglas Gregor   // reset them to their default values.
8218cf47df7STed Kremenek   Invocation->getLangOpts()->resetNonModularOptions();
822f545f67dSDouglas Gregor   PPOpts.resetNonModularOptions();
82344bf68d8SDouglas Gregor 
8245dc3899cSDouglas Gregor   // Remove any macro definitions that are explicitly ignored by the module.
8255dc3899cSDouglas Gregor   // They aren't supposed to affect how the module is built anyway.
8265dc3899cSDouglas Gregor   const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
8275dc3899cSDouglas Gregor   PPOpts.Macros.erase(std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(),
8285dc3899cSDouglas Gregor                                      RemoveIgnoredMacro(HSOpts)),
8295dc3899cSDouglas Gregor                       PPOpts.Macros.end());
8305dc3899cSDouglas Gregor 
8315dc3899cSDouglas Gregor 
8327d106e42SDouglas Gregor   // Note the name of the module we're building.
8336dc57927SDouglas Gregor   Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName();
8347d106e42SDouglas Gregor 
8357a626570SDouglas Gregor   // Make sure that the failed-module structure has been allocated in
8367a626570SDouglas Gregor   // the importing instance, and propagate the pointer to the newly-created
8377a626570SDouglas Gregor   // instance.
8387a626570SDouglas Gregor   PreprocessorOptions &ImportingPPOpts
8397a626570SDouglas Gregor     = ImportingInstance.getInvocation().getPreprocessorOpts();
8407a626570SDouglas Gregor   if (!ImportingPPOpts.FailedModules)
8417a626570SDouglas Gregor     ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet;
8427a626570SDouglas Gregor   PPOpts.FailedModules = ImportingPPOpts.FailedModules;
8437a626570SDouglas Gregor 
844514b636aSDouglas Gregor   // If there is a module map file, build the module using the module map.
845514b636aSDouglas Gregor   // Set up the inputs/outputs so that we build the module from its umbrella
846514b636aSDouglas Gregor   // header.
847514b636aSDouglas Gregor   FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
848514b636aSDouglas Gregor   FrontendOpts.OutputFile = ModuleFileName.str();
849514b636aSDouglas Gregor   FrontendOpts.DisableFree = false;
850c1bbec85SDouglas Gregor   FrontendOpts.GenerateGlobalModuleIndex = false;
851514b636aSDouglas Gregor   FrontendOpts.Inputs.clear();
852f545f67dSDouglas Gregor   InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts());
853f545f67dSDouglas Gregor 
854f545f67dSDouglas Gregor   // Don't free the remapped file buffers; they are owned by our caller.
855f545f67dSDouglas Gregor   PPOpts.RetainRemappedFileBuffers = true;
856514b636aSDouglas Gregor 
857514b636aSDouglas Gregor   Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
858514b636aSDouglas Gregor   assert(ImportingInstance.getInvocation().getModuleHash() ==
859514b636aSDouglas Gregor          Invocation->getModuleHash() && "Module hash mismatch!");
860514b636aSDouglas Gregor 
861514b636aSDouglas Gregor   // Construct a compiler instance that will be used to actually create the
862514b636aSDouglas Gregor   // module.
863514b636aSDouglas Gregor   CompilerInstance Instance;
864514b636aSDouglas Gregor   Instance.setInvocation(&*Invocation);
8656b930967SDouglas Gregor 
8666b930967SDouglas Gregor   Instance.createDiagnostics(new ForwardingDiagnosticConsumer(
8676b930967SDouglas Gregor                                    ImportingInstance.getDiagnosticClient()),
86830071ceaSDouglas Gregor                              /*ShouldOwnClient=*/true);
869514b636aSDouglas Gregor 
87063365431SDouglas Gregor   // Note that this module is part of the module build stack, so that we
871af8f0263SDouglas Gregor   // can detect cycles in the module graph.
872af8f0263SDouglas Gregor   Instance.createFileManager(); // FIXME: Adopt file manager from importer?
873af8f0263SDouglas Gregor   Instance.createSourceManager(Instance.getFileManager());
874af8f0263SDouglas Gregor   SourceManager &SourceMgr = Instance.getSourceManager();
87563365431SDouglas Gregor   SourceMgr.setModuleBuildStack(
87663365431SDouglas Gregor     ImportingInstance.getSourceManager().getModuleBuildStack());
87763365431SDouglas Gregor   SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(),
878af8f0263SDouglas Gregor     FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));
879af8f0263SDouglas Gregor 
8801f76c4e8SManuel Klimek   // Get or create the module map that we'll use to build this module.
8811f76c4e8SManuel Klimek   std::string InferredModuleMapContent;
8821f76c4e8SManuel Klimek   if (const FileEntry *ModuleMapFile =
8831f76c4e8SManuel Klimek           ModMap.getContainingModuleMapFile(Module)) {
8841f76c4e8SManuel Klimek     // Use the module map where this module resides.
8851f76c4e8SManuel Klimek     FrontendOpts.Inputs.push_back(
8861f76c4e8SManuel Klimek         FrontendInputFile(ModuleMapFile->getName(), IK));
8871f76c4e8SManuel Klimek   } else {
8881f76c4e8SManuel Klimek     llvm::raw_string_ostream OS(InferredModuleMapContent);
8891f76c4e8SManuel Klimek     Module->print(OS);
8901f76c4e8SManuel Klimek     OS.flush();
8911f76c4e8SManuel Klimek     FrontendOpts.Inputs.push_back(
8921f76c4e8SManuel Klimek         FrontendInputFile("__inferred_module.map", IK));
8931f76c4e8SManuel Klimek 
8941f76c4e8SManuel Klimek     const llvm::MemoryBuffer *ModuleMapBuffer =
8951f76c4e8SManuel Klimek         llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
8961f76c4e8SManuel Klimek     ModuleMapFile = Instance.getFileManager().getVirtualFile(
8971f76c4e8SManuel Klimek         "__inferred_module.map", InferredModuleMapContent.size(), 0);
8981f76c4e8SManuel Klimek     SourceMgr.overrideFileContents(ModuleMapFile, ModuleMapBuffer);
8991f76c4e8SManuel Klimek   }
900af8f0263SDouglas Gregor 
901514b636aSDouglas Gregor   // Construct a module-generating action.
902963c5535SDouglas Gregor   GenerateModuleAction CreateModuleAction(Module->IsSystem);
903514b636aSDouglas Gregor 
904514b636aSDouglas Gregor   // Execute the action to actually build the module in-place. Use a separate
905514b636aSDouglas Gregor   // thread so that we get a stack large enough.
906514b636aSDouglas Gregor   const unsigned ThreadStackSize = 8 << 20;
907514b636aSDouglas Gregor   llvm::CrashRecoveryContext CRC;
908514b636aSDouglas Gregor   CompileModuleMapData Data = { Instance, CreateModuleAction };
909514b636aSDouglas Gregor   CRC.RunSafelyOnThread(&doCompileMapModule, &Data, ThreadStackSize);
910514b636aSDouglas Gregor 
9116b930967SDouglas Gregor 
912f545f67dSDouglas Gregor   // Delete the temporary module map file.
913f545f67dSDouglas Gregor   // FIXME: Even though we're executing under crash protection, it would still
914f545f67dSDouglas Gregor   // be nice to do this with RemoveFileOnSignal when we can. However, that
915f545f67dSDouglas Gregor   // doesn't make sense for all clients, so clean this up manually.
91613afbf42SBenjamin Kramer   Instance.clearOutputFiles(/*EraseFiles=*/true);
9175e306b12SDouglas Gregor 
9185e306b12SDouglas Gregor   // We've rebuilt a module. If we're allowed to generate or update the global
9195e306b12SDouglas Gregor   // module index, record that fact in the importing compiler instance.
920c1bbec85SDouglas Gregor   if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) {
9215e306b12SDouglas Gregor     ImportingInstance.setBuildGlobalModuleIndex(true);
9225e306b12SDouglas Gregor   }
923faeb1d46SDouglas Gregor }
924faeb1d46SDouglas Gregor 
92535b13eceSDouglas Gregor /// \brief Diagnose differences between the current definition of the given
92635b13eceSDouglas Gregor /// configuration macro and the definition provided on the command line.
92735b13eceSDouglas Gregor static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,
92835b13eceSDouglas Gregor                              Module *Mod, SourceLocation ImportLoc) {
92935b13eceSDouglas Gregor   IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro);
93035b13eceSDouglas Gregor   SourceManager &SourceMgr = PP.getSourceManager();
93135b13eceSDouglas Gregor 
93235b13eceSDouglas Gregor   // If this identifier has never had a macro definition, then it could
93335b13eceSDouglas Gregor   // not have changed.
93435b13eceSDouglas Gregor   if (!Id->hadMacroDefinition())
93535b13eceSDouglas Gregor     return;
93635b13eceSDouglas Gregor 
93735b13eceSDouglas Gregor   // If this identifier does not currently have a macro definition,
93835b13eceSDouglas Gregor   // check whether it had one on the command line.
93935b13eceSDouglas Gregor   if (!Id->hasMacroDefinition()) {
940b6210dffSArgyrios Kyrtzidis     MacroDirective::DefInfo LatestDef =
941b6210dffSArgyrios Kyrtzidis         PP.getMacroDirectiveHistory(Id)->getDefinition();
942b6210dffSArgyrios Kyrtzidis     for (MacroDirective::DefInfo Def = LatestDef; Def;
943b6210dffSArgyrios Kyrtzidis            Def = Def.getPreviousDefinition()) {
944b6210dffSArgyrios Kyrtzidis       FileID FID = SourceMgr.getFileID(Def.getLocation());
94535b13eceSDouglas Gregor       if (FID.isInvalid())
94635b13eceSDouglas Gregor         continue;
94735b13eceSDouglas Gregor 
94835b13eceSDouglas Gregor       // We only care about the predefines buffer.
94905ba2a05SDouglas Gregor       if (FID != PP.getPredefinesFileID())
95035b13eceSDouglas Gregor         continue;
95135b13eceSDouglas Gregor 
95235b13eceSDouglas Gregor       // This macro was defined on the command line, then #undef'd later.
95335b13eceSDouglas Gregor       // Complain.
95435b13eceSDouglas Gregor       PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
95535b13eceSDouglas Gregor         << true << ConfigMacro << Mod->getFullModuleName();
956b6210dffSArgyrios Kyrtzidis       if (LatestDef.isUndefined())
957b6210dffSArgyrios Kyrtzidis         PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
95835b13eceSDouglas Gregor           << true;
95935b13eceSDouglas Gregor       return;
96035b13eceSDouglas Gregor     }
96135b13eceSDouglas Gregor 
96235b13eceSDouglas Gregor     // Okay: no definition in the predefines buffer.
96335b13eceSDouglas Gregor     return;
96435b13eceSDouglas Gregor   }
96535b13eceSDouglas Gregor 
96635b13eceSDouglas Gregor   // This identifier has a macro definition. Check whether we had a definition
96735b13eceSDouglas Gregor   // on the command line.
968b6210dffSArgyrios Kyrtzidis   MacroDirective::DefInfo LatestDef =
969b6210dffSArgyrios Kyrtzidis       PP.getMacroDirectiveHistory(Id)->getDefinition();
970b6210dffSArgyrios Kyrtzidis   MacroDirective::DefInfo PredefinedDef;
971b6210dffSArgyrios Kyrtzidis   for (MacroDirective::DefInfo Def = LatestDef; Def;
972b6210dffSArgyrios Kyrtzidis          Def = Def.getPreviousDefinition()) {
973b6210dffSArgyrios Kyrtzidis     FileID FID = SourceMgr.getFileID(Def.getLocation());
97435b13eceSDouglas Gregor     if (FID.isInvalid())
97535b13eceSDouglas Gregor       continue;
97635b13eceSDouglas Gregor 
97735b13eceSDouglas Gregor     // We only care about the predefines buffer.
97805ba2a05SDouglas Gregor     if (FID != PP.getPredefinesFileID())
97935b13eceSDouglas Gregor       continue;
98035b13eceSDouglas Gregor 
981b6210dffSArgyrios Kyrtzidis     PredefinedDef = Def;
98235b13eceSDouglas Gregor     break;
98335b13eceSDouglas Gregor   }
98435b13eceSDouglas Gregor 
98535b13eceSDouglas Gregor   // If there was no definition for this macro in the predefines buffer,
98635b13eceSDouglas Gregor   // complain.
987b6210dffSArgyrios Kyrtzidis   if (!PredefinedDef ||
988b6210dffSArgyrios Kyrtzidis       (!PredefinedDef.getLocation().isValid() &&
989b6210dffSArgyrios Kyrtzidis        PredefinedDef.getUndefLocation().isValid())) {
99035b13eceSDouglas Gregor     PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
99135b13eceSDouglas Gregor       << false << ConfigMacro << Mod->getFullModuleName();
992b6210dffSArgyrios Kyrtzidis     PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
99335b13eceSDouglas Gregor       << false;
99435b13eceSDouglas Gregor     return;
99535b13eceSDouglas Gregor   }
99635b13eceSDouglas Gregor 
99735b13eceSDouglas Gregor   // If the current macro definition is the same as the predefined macro
99835b13eceSDouglas Gregor   // definition, it's okay.
999b6210dffSArgyrios Kyrtzidis   if (LatestDef.getMacroInfo() == PredefinedDef.getMacroInfo() ||
10000c2f30b9SArgyrios Kyrtzidis       LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP,
10010c2f30b9SArgyrios Kyrtzidis                                               /*Syntactically=*/true))
100235b13eceSDouglas Gregor     return;
100335b13eceSDouglas Gregor 
100435b13eceSDouglas Gregor   // The macro definitions differ.
100535b13eceSDouglas Gregor   PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
100635b13eceSDouglas Gregor     << false << ConfigMacro << Mod->getFullModuleName();
1007b6210dffSArgyrios Kyrtzidis   PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
100835b13eceSDouglas Gregor     << false;
100935b13eceSDouglas Gregor }
101035b13eceSDouglas Gregor 
1011527b1c95SDouglas Gregor /// \brief Write a new timestamp file with the given path.
1012527b1c95SDouglas Gregor static void writeTimestampFile(StringRef TimestampFile) {
1013527b1c95SDouglas Gregor   std::string ErrorInfo;
1014527b1c95SDouglas Gregor   llvm::raw_fd_ostream Out(TimestampFile.str().c_str(), ErrorInfo,
101516125fb6SRafael Espindola                            llvm::sys::fs::F_Binary);
1016527b1c95SDouglas Gregor }
1017527b1c95SDouglas Gregor 
1018527b1c95SDouglas Gregor /// \brief Prune the module cache of modules that haven't been accessed in
1019527b1c95SDouglas Gregor /// a long time.
1020527b1c95SDouglas Gregor static void pruneModuleCache(const HeaderSearchOptions &HSOpts) {
1021527b1c95SDouglas Gregor   struct stat StatBuf;
1022527b1c95SDouglas Gregor   llvm::SmallString<128> TimestampFile;
1023527b1c95SDouglas Gregor   TimestampFile = HSOpts.ModuleCachePath;
1024527b1c95SDouglas Gregor   llvm::sys::path::append(TimestampFile, "modules.timestamp");
1025527b1c95SDouglas Gregor 
1026527b1c95SDouglas Gregor   // Try to stat() the timestamp file.
1027527b1c95SDouglas Gregor   if (::stat(TimestampFile.c_str(), &StatBuf)) {
1028527b1c95SDouglas Gregor     // If the timestamp file wasn't there, create one now.
1029527b1c95SDouglas Gregor     if (errno == ENOENT) {
1030527b1c95SDouglas Gregor       writeTimestampFile(TimestampFile);
1031527b1c95SDouglas Gregor     }
1032527b1c95SDouglas Gregor     return;
1033527b1c95SDouglas Gregor   }
1034527b1c95SDouglas Gregor 
1035527b1c95SDouglas Gregor   // Check whether the time stamp is older than our pruning interval.
1036527b1c95SDouglas Gregor   // If not, do nothing.
1037527b1c95SDouglas Gregor   time_t TimeStampModTime = StatBuf.st_mtime;
1038527b1c95SDouglas Gregor   time_t CurrentTime = time(0);
1039dbcf5037SBenjamin Kramer   if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval))
1040527b1c95SDouglas Gregor     return;
1041527b1c95SDouglas Gregor 
1042527b1c95SDouglas Gregor   // Write a new timestamp file so that nobody else attempts to prune.
1043527b1c95SDouglas Gregor   // There is a benign race condition here, if two Clang instances happen to
1044527b1c95SDouglas Gregor   // notice at the same time that the timestamp is out-of-date.
1045527b1c95SDouglas Gregor   writeTimestampFile(TimestampFile);
1046527b1c95SDouglas Gregor 
1047527b1c95SDouglas Gregor   // Walk the entire module cache, looking for unused module files and module
1048527b1c95SDouglas Gregor   // indices.
1049527b1c95SDouglas Gregor   llvm::error_code EC;
1050527b1c95SDouglas Gregor   SmallString<128> ModuleCachePathNative;
1051527b1c95SDouglas Gregor   llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative);
1052527b1c95SDouglas Gregor   for (llvm::sys::fs::directory_iterator
1053527b1c95SDouglas Gregor          Dir(ModuleCachePathNative.str(), EC), DirEnd;
1054527b1c95SDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
1055527b1c95SDouglas Gregor     // If we don't have a directory, there's nothing to look into.
1056a07f720aSRafael Espindola     if (!llvm::sys::fs::is_directory(Dir->path()))
1057527b1c95SDouglas Gregor       continue;
1058527b1c95SDouglas Gregor 
1059527b1c95SDouglas Gregor     // Walk all of the files within this directory.
1060527b1c95SDouglas Gregor     bool RemovedAllFiles = true;
1061527b1c95SDouglas Gregor     for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd;
1062527b1c95SDouglas Gregor          File != FileEnd && !EC; File.increment(EC)) {
1063527b1c95SDouglas Gregor       // We only care about module and global module index files.
1064527b1c95SDouglas Gregor       if (llvm::sys::path::extension(File->path()) != ".pcm" &&
1065527b1c95SDouglas Gregor           llvm::sys::path::filename(File->path()) != "modules.idx") {
1066527b1c95SDouglas Gregor         RemovedAllFiles = false;
1067527b1c95SDouglas Gregor         continue;
1068527b1c95SDouglas Gregor       }
1069527b1c95SDouglas Gregor 
1070527b1c95SDouglas Gregor       // Look at this file. If we can't stat it, there's nothing interesting
1071527b1c95SDouglas Gregor       // there.
1072527b1c95SDouglas Gregor       if (::stat(File->path().c_str(), &StatBuf)) {
1073527b1c95SDouglas Gregor         RemovedAllFiles = false;
1074527b1c95SDouglas Gregor         continue;
1075527b1c95SDouglas Gregor       }
1076527b1c95SDouglas Gregor 
1077527b1c95SDouglas Gregor       // If the file has been used recently enough, leave it there.
1078527b1c95SDouglas Gregor       time_t FileAccessTime = StatBuf.st_atime;
1079dbcf5037SBenjamin Kramer       if (CurrentTime - FileAccessTime <=
1080dbcf5037SBenjamin Kramer               time_t(HSOpts.ModuleCachePruneAfter)) {
1081dbcf5037SBenjamin Kramer         RemovedAllFiles = false;
1082527b1c95SDouglas Gregor         continue;
1083527b1c95SDouglas Gregor       }
1084527b1c95SDouglas Gregor 
1085527b1c95SDouglas Gregor       // Remove the file.
1086527b1c95SDouglas Gregor       bool Existed;
1087527b1c95SDouglas Gregor       if (llvm::sys::fs::remove(File->path(), Existed) || !Existed) {
1088527b1c95SDouglas Gregor         RemovedAllFiles = false;
1089527b1c95SDouglas Gregor       }
1090527b1c95SDouglas Gregor     }
1091527b1c95SDouglas Gregor 
1092527b1c95SDouglas Gregor     // If we removed all of the files in the directory, remove the directory
1093527b1c95SDouglas Gregor     // itself.
1094527b1c95SDouglas Gregor     if (RemovedAllFiles) {
1095527b1c95SDouglas Gregor       bool Existed;
1096527b1c95SDouglas Gregor       llvm::sys::fs::remove(Dir->path(), Existed);
1097527b1c95SDouglas Gregor     }
1098527b1c95SDouglas Gregor   }
1099527b1c95SDouglas Gregor }
1100527b1c95SDouglas Gregor 
11017a626570SDouglas Gregor ModuleLoadResult
11027a626570SDouglas Gregor CompilerInstance::loadModule(SourceLocation ImportLoc,
1103ff2be53fSDouglas Gregor                              ModuleIdPath Path,
1104bcfc7d02SDouglas Gregor                              Module::NameVisibilityKind Visibility,
1105bcfc7d02SDouglas Gregor                              bool IsInclusionDirective) {
110692304e00SRichard Smith   // Determine what file we're searching from.
110792304e00SRichard Smith   StringRef ModuleName = Path[0].first->getName();
110892304e00SRichard Smith   SourceLocation ModuleNameLoc = Path[0].second;
110992304e00SRichard Smith 
11101805b8a4SDouglas Gregor   // If we've already handled this import, just return the cached result.
11111805b8a4SDouglas Gregor   // This one-element cache is important to eliminate redundant diagnostics
11121805b8a4SDouglas Gregor   // when both the preprocessor and parser see the same import declaration.
1113ff2be53fSDouglas Gregor   if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) {
1114ff2be53fSDouglas Gregor     // Make the named module visible.
111592304e00SRichard Smith     if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule)
1116125df058SArgyrios Kyrtzidis       ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility,
1117fb912657SDouglas Gregor                                        ImportLoc, /*Complain=*/false);
111869021974SDouglas Gregor     return LastModuleImportResult;
1119ff2be53fSDouglas Gregor   }
11201805b8a4SDouglas Gregor 
1121de3ef502SDouglas Gregor   clang::Module *Module = 0;
11225196bc6bSDouglas Gregor 
11235196bc6bSDouglas Gregor   // If we don't already have information on this module, load the module now.
1124de3ef502SDouglas Gregor   llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known
112569021974SDouglas Gregor     = KnownModules.find(Path[0].first);
11262537a364SDouglas Gregor   if (Known != KnownModules.end()) {
11272537a364SDouglas Gregor     // Retrieve the cached top-level module.
11282537a364SDouglas Gregor     Module = Known->second;
11292537a364SDouglas Gregor   } else if (ModuleName == getLangOpts().CurrentModule) {
11302537a364SDouglas Gregor     // This is the module we're building.
11312537a364SDouglas Gregor     Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName);
11322537a364SDouglas Gregor     Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
11332537a364SDouglas Gregor   } else {
11345196bc6bSDouglas Gregor     // Search for a module with the given name.
1135279a6c37SDouglas Gregor     Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
11361735f4e7SDouglas Gregor     std::string ModuleFileName;
11378a114ab5SDouglas Gregor     if (Module) {
1138279a6c37SDouglas Gregor       ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module);
11398a114ab5SDouglas Gregor     } else
1140279a6c37SDouglas Gregor       ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName);
1141faeb1d46SDouglas Gregor 
114208142534SDouglas Gregor     // If we don't already have an ASTReader, create one now.
114308142534SDouglas Gregor     if (!ModuleManager) {
114421931efcSDouglas Gregor       if (!hasASTContext())
114521931efcSDouglas Gregor         createASTContext();
114621931efcSDouglas Gregor 
1147527b1c95SDouglas Gregor       // If we're not recursively building a module, check whether we
1148527b1c95SDouglas Gregor       // need to prune the module cache.
1149527b1c95SDouglas Gregor       if (getSourceManager().getModuleBuildStack().empty() &&
1150527b1c95SDouglas Gregor           getHeaderSearchOpts().ModuleCachePruneInterval > 0 &&
1151527b1c95SDouglas Gregor           getHeaderSearchOpts().ModuleCachePruneAfter > 0) {
1152527b1c95SDouglas Gregor         pruneModuleCache(getHeaderSearchOpts());
1153527b1c95SDouglas Gregor       }
1154527b1c95SDouglas Gregor 
115508142534SDouglas Gregor       std::string Sysroot = getHeaderSearchOpts().Sysroot;
115608142534SDouglas Gregor       const PreprocessorOptions &PPOpts = getPreprocessorOpts();
11578835e03cSDouglas Gregor       ModuleManager = new ASTReader(getPreprocessor(), *Context,
115808142534SDouglas Gregor                                     Sysroot.empty() ? "" : Sysroot.c_str(),
1159c1bbec85SDouglas Gregor                                     PPOpts.DisablePCHValidation,
1160c1bbec85SDouglas Gregor                                     /*AllowASTWithCompilerErrors=*/false,
1161c1bbec85SDouglas Gregor                                     getFrontendOpts().UseGlobalModuleIndex);
116221931efcSDouglas Gregor       if (hasASTConsumer()) {
116308142534SDouglas Gregor         ModuleManager->setDeserializationListener(
116408142534SDouglas Gregor           getASTConsumer().GetASTDeserializationListener());
116508142534SDouglas Gregor         getASTContext().setASTMutationListener(
116608142534SDouglas Gregor           getASTConsumer().GetASTMutationListener());
116721931efcSDouglas Gregor       }
1168e2778999SDylan Noblesmith       OwningPtr<ExternalASTSource> Source;
116908142534SDouglas Gregor       Source.reset(ModuleManager);
117008142534SDouglas Gregor       getASTContext().setExternalSource(Source);
117121931efcSDouglas Gregor       if (hasSema())
117208142534SDouglas Gregor         ModuleManager->InitializeSema(getSema());
11736137d32cSDouglas Gregor       if (hasASTConsumer())
11746137d32cSDouglas Gregor         ModuleManager->StartTranslationUnit(&getASTConsumer());
117508142534SDouglas Gregor     }
117608142534SDouglas Gregor 
11777029ce1aSDouglas Gregor     // Try to load the module file.
11787029ce1aSDouglas Gregor     unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
11797029ce1aSDouglas Gregor     switch (ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module,
11807029ce1aSDouglas Gregor                                    ImportLoc, ARRFlags)) {
118108142534SDouglas Gregor     case ASTReader::Success:
118208142534SDouglas Gregor       break;
118308142534SDouglas Gregor 
1184963ff2c3SEli Friedman     case ASTReader::OutOfDate:
11857029ce1aSDouglas Gregor     case ASTReader::Missing: {
1186963ff2c3SEli Friedman       // The module file is missing or out-of-date. Build it.
11877029ce1aSDouglas Gregor 
11887029ce1aSDouglas Gregor       // If we don't have a module, we don't know how to build the module file.
11897029ce1aSDouglas Gregor       // Complain and return.
11907029ce1aSDouglas Gregor       if (!Module) {
11917029ce1aSDouglas Gregor         getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
11927029ce1aSDouglas Gregor           << ModuleName
11937029ce1aSDouglas Gregor           << SourceRange(ImportLoc, ModuleNameLoc);
11947029ce1aSDouglas Gregor         ModuleBuildFailed = true;
11957029ce1aSDouglas Gregor         return ModuleLoadResult();
11967029ce1aSDouglas Gregor       }
11977029ce1aSDouglas Gregor 
11987029ce1aSDouglas Gregor       // Check whether there is a cycle in the module graph.
11997029ce1aSDouglas Gregor       ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack();
12007029ce1aSDouglas Gregor       ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
12017029ce1aSDouglas Gregor       for (; Pos != PosEnd; ++Pos) {
12027029ce1aSDouglas Gregor         if (Pos->first == ModuleName)
12037029ce1aSDouglas Gregor           break;
12047029ce1aSDouglas Gregor       }
12057029ce1aSDouglas Gregor 
12067029ce1aSDouglas Gregor       if (Pos != PosEnd) {
12077029ce1aSDouglas Gregor         SmallString<256> CyclePath;
12087029ce1aSDouglas Gregor         for (; Pos != PosEnd; ++Pos) {
12097029ce1aSDouglas Gregor           CyclePath += Pos->first;
12107029ce1aSDouglas Gregor           CyclePath += " -> ";
12117029ce1aSDouglas Gregor         }
12127029ce1aSDouglas Gregor         CyclePath += ModuleName;
12137029ce1aSDouglas Gregor 
12147029ce1aSDouglas Gregor         getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle)
12157029ce1aSDouglas Gregor           << ModuleName << CyclePath;
12167029ce1aSDouglas Gregor         return ModuleLoadResult();
12177029ce1aSDouglas Gregor       }
12187a626570SDouglas Gregor 
12197a626570SDouglas Gregor       // Check whether we have already attempted to build this module (but
12207a626570SDouglas Gregor       // failed).
12217a626570SDouglas Gregor       if (getPreprocessorOpts().FailedModules &&
12227a626570SDouglas Gregor           getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) {
12237a626570SDouglas Gregor         getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built)
12247a626570SDouglas Gregor           << ModuleName
12257a626570SDouglas Gregor           << SourceRange(ImportLoc, ModuleNameLoc);
1226c1bbec85SDouglas Gregor         ModuleBuildFailed = true;
12277a626570SDouglas Gregor         return ModuleLoadResult();
12287a626570SDouglas Gregor       }
12297a626570SDouglas Gregor 
12307029ce1aSDouglas Gregor       // Try to compile the module.
1231af8f0263SDouglas Gregor       compileModule(*this, ModuleNameLoc, Module, ModuleFileName);
1232188dbef2SDouglas Gregor 
12337029ce1aSDouglas Gregor       // Try to read the module file, now that we've compiled it.
12347029ce1aSDouglas Gregor       ASTReader::ASTReadResult ReadResult
12357029ce1aSDouglas Gregor         = ModuleManager->ReadAST(ModuleFileName,
12362ec29367SArgyrios Kyrtzidis                                  serialization::MK_Module, ImportLoc,
12377029ce1aSDouglas Gregor                                  ASTReader::ARR_Missing);
12387029ce1aSDouglas Gregor       if (ReadResult != ASTReader::Success) {
12397029ce1aSDouglas Gregor         if (ReadResult == ASTReader::Missing) {
12407029ce1aSDouglas Gregor           getDiagnostics().Report(ModuleNameLoc,
12417029ce1aSDouglas Gregor                                   Module? diag::err_module_not_built
12427029ce1aSDouglas Gregor                                         : diag::err_module_not_found)
12437029ce1aSDouglas Gregor             << ModuleName
12447029ce1aSDouglas Gregor             << SourceRange(ImportLoc, ModuleNameLoc);
12457029ce1aSDouglas Gregor         }
12467029ce1aSDouglas Gregor 
12470f2b4635SDouglas Gregor         if (getPreprocessorOpts().FailedModules)
12487a626570SDouglas Gregor           getPreprocessorOpts().FailedModules->addFailed(ModuleName);
1249188dbef2SDouglas Gregor         KnownModules[Path[0].first] = 0;
1250c1bbec85SDouglas Gregor         ModuleBuildFailed = true;
12517a626570SDouglas Gregor         return ModuleLoadResult();
1252188dbef2SDouglas Gregor       }
1253188dbef2SDouglas Gregor 
1254188dbef2SDouglas Gregor       // Okay, we've rebuilt and now loaded the module.
1255188dbef2SDouglas Gregor       break;
1256188dbef2SDouglas Gregor     }
1257188dbef2SDouglas Gregor 
1258c9ad5fb6SDouglas Gregor     case ASTReader::VersionMismatch:
1259c9ad5fb6SDouglas Gregor     case ASTReader::ConfigurationMismatch:
1260c9ad5fb6SDouglas Gregor     case ASTReader::HadErrors:
1261dc9fdaf2SArgyrios Kyrtzidis       ModuleLoader::HadFatalFailure = true;
126208142534SDouglas Gregor       // FIXME: The ASTReader will already have complained, but can we showhorn
126308142534SDouglas Gregor       // that diagnostic information into a more useful form?
126469021974SDouglas Gregor       KnownModules[Path[0].first] = 0;
12657a626570SDouglas Gregor       return ModuleLoadResult();
126608142534SDouglas Gregor 
126708142534SDouglas Gregor     case ASTReader::Failure:
1268dc9fdaf2SArgyrios Kyrtzidis       ModuleLoader::HadFatalFailure = true;
126969021974SDouglas Gregor       // Already complained, but note now that we failed.
127069021974SDouglas Gregor       KnownModules[Path[0].first] = 0;
1271c1bbec85SDouglas Gregor       ModuleBuildFailed = true;
12727a626570SDouglas Gregor       return ModuleLoadResult();
127308142534SDouglas Gregor     }
127408142534SDouglas Gregor 
127569021974SDouglas Gregor     if (!Module) {
127669021974SDouglas Gregor       // If we loaded the module directly, without finding a module map first,
127769021974SDouglas Gregor       // we'll have loaded the module's information from the module itself.
127869021974SDouglas Gregor       Module = PP->getHeaderSearchInfo().getModuleMap()
127969021974SDouglas Gregor                  .findModule((Path[0].first->getName()));
12805196bc6bSDouglas Gregor     }
128143af5132SArgyrios Kyrtzidis 
128269021974SDouglas Gregor     // Cache the result of this top-level module lookup for later.
128369021974SDouglas Gregor     Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
128469021974SDouglas Gregor   }
128569021974SDouglas Gregor 
128669021974SDouglas Gregor   // If we never found the module, fail.
128769021974SDouglas Gregor   if (!Module)
12887a626570SDouglas Gregor     return ModuleLoadResult();
128969021974SDouglas Gregor 
12905196bc6bSDouglas Gregor   // Verify that the rest of the module path actually corresponds to
12915196bc6bSDouglas Gregor   // a submodule.
129269021974SDouglas Gregor   if (Path.size() > 1) {
12935196bc6bSDouglas Gregor     for (unsigned I = 1, N = Path.size(); I != N; ++I) {
12945196bc6bSDouglas Gregor       StringRef Name = Path[I].first->getName();
1295eb90e830SDouglas Gregor       clang::Module *Sub = Module->findSubmodule(Name);
12965196bc6bSDouglas Gregor 
1297eb90e830SDouglas Gregor       if (!Sub) {
12985196bc6bSDouglas Gregor         // Attempt to perform typo correction to find a module name that works.
1299f857950dSDmitri Gribenko         SmallVector<StringRef, 2> Best;
13005196bc6bSDouglas Gregor         unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
13015196bc6bSDouglas Gregor 
1302eb90e830SDouglas Gregor         for (clang::Module::submodule_iterator J = Module->submodule_begin(),
1303eb90e830SDouglas Gregor                                             JEnd = Module->submodule_end();
1304eb44edadSMatt Beaumont-Gay              J != JEnd; ++J) {
1305eb90e830SDouglas Gregor           unsigned ED = Name.edit_distance((*J)->Name,
13065196bc6bSDouglas Gregor                                            /*AllowReplacements=*/true,
13075196bc6bSDouglas Gregor                                            BestEditDistance);
13085196bc6bSDouglas Gregor           if (ED <= BestEditDistance) {
1309eb90e830SDouglas Gregor             if (ED < BestEditDistance) {
13105196bc6bSDouglas Gregor               Best.clear();
1311eb90e830SDouglas Gregor               BestEditDistance = ED;
1312eb90e830SDouglas Gregor             }
1313eb90e830SDouglas Gregor 
1314eb90e830SDouglas Gregor             Best.push_back((*J)->Name);
13155196bc6bSDouglas Gregor           }
13165196bc6bSDouglas Gregor         }
13175196bc6bSDouglas Gregor 
13185196bc6bSDouglas Gregor         // If there was a clear winner, user it.
13195196bc6bSDouglas Gregor         if (Best.size() == 1) {
13205196bc6bSDouglas Gregor           getDiagnostics().Report(Path[I].second,
13215196bc6bSDouglas Gregor                                   diag::err_no_submodule_suggest)
132269021974SDouglas Gregor             << Path[I].first << Module->getFullModuleName() << Best[0]
13235196bc6bSDouglas Gregor             << SourceRange(Path[0].second, Path[I-1].second)
13245196bc6bSDouglas Gregor             << FixItHint::CreateReplacement(SourceRange(Path[I].second),
13255196bc6bSDouglas Gregor                                             Best[0]);
1326eb90e830SDouglas Gregor 
1327eb90e830SDouglas Gregor           Sub = Module->findSubmodule(Best[0]);
13285196bc6bSDouglas Gregor         }
13295196bc6bSDouglas Gregor       }
13305196bc6bSDouglas Gregor 
1331eb90e830SDouglas Gregor       if (!Sub) {
13325196bc6bSDouglas Gregor         // No submodule by this name. Complain, and don't look for further
13335196bc6bSDouglas Gregor         // submodules.
13345196bc6bSDouglas Gregor         getDiagnostics().Report(Path[I].second, diag::err_no_submodule)
133569021974SDouglas Gregor           << Path[I].first << Module->getFullModuleName()
13365196bc6bSDouglas Gregor           << SourceRange(Path[0].second, Path[I-1].second);
13375196bc6bSDouglas Gregor         break;
13385196bc6bSDouglas Gregor       }
13395196bc6bSDouglas Gregor 
1340eb90e830SDouglas Gregor       Module = Sub;
13415196bc6bSDouglas Gregor     }
13425196bc6bSDouglas Gregor   }
13435196bc6bSDouglas Gregor 
13442537a364SDouglas Gregor   // Make the named module visible, if it's not already part of the module
13452537a364SDouglas Gregor   // we are parsing.
134698a52db8SDouglas Gregor   if (ModuleName != getLangOpts().CurrentModule) {
134798a52db8SDouglas Gregor     if (!Module->IsFromModuleFile) {
134898a52db8SDouglas Gregor       // We have an umbrella header or directory that doesn't actually include
134998a52db8SDouglas Gregor       // all of the headers within the directory it covers. Complain about
135098a52db8SDouglas Gregor       // this missing submodule and recover by forgetting that we ever saw
135198a52db8SDouglas Gregor       // this submodule.
135298a52db8SDouglas Gregor       // FIXME: Should we detect this at module load time? It seems fairly
135398a52db8SDouglas Gregor       // expensive (and rare).
135498a52db8SDouglas Gregor       getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule)
135598a52db8SDouglas Gregor         << Module->getFullModuleName()
135698a52db8SDouglas Gregor         << SourceRange(Path.front().second, Path.back().second);
135798a52db8SDouglas Gregor 
13587a626570SDouglas Gregor       return ModuleLoadResult(0, true);
135998a52db8SDouglas Gregor     }
13601fb5c3a6SDouglas Gregor 
13611fb5c3a6SDouglas Gregor     // Check whether this module is available.
1362*a3feee2aSRichard Smith     clang::Module::Requirement Requirement;
1363*a3feee2aSRichard Smith     if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement)) {
13641fb5c3a6SDouglas Gregor       getDiagnostics().Report(ImportLoc, diag::err_module_unavailable)
13651fb5c3a6SDouglas Gregor         << Module->getFullModuleName()
1366*a3feee2aSRichard Smith         << Requirement.second << Requirement.first
13671fb5c3a6SDouglas Gregor         << SourceRange(Path.front().second, Path.back().second);
13681fb5c3a6SDouglas Gregor       LastModuleImportLoc = ImportLoc;
13697a626570SDouglas Gregor       LastModuleImportResult = ModuleLoadResult();
13707a626570SDouglas Gregor       return ModuleLoadResult();
13711fb5c3a6SDouglas Gregor     }
13721fb5c3a6SDouglas Gregor 
1373fb912657SDouglas Gregor     ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc,
1374fb912657SDouglas Gregor                                      /*Complain=*/true);
137598a52db8SDouglas Gregor   }
13765196bc6bSDouglas Gregor 
137735b13eceSDouglas Gregor   // Check for any configuration macros that have changed.
137835b13eceSDouglas Gregor   clang::Module *TopModule = Module->getTopLevelModule();
137935b13eceSDouglas Gregor   for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) {
138035b13eceSDouglas Gregor     checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I],
138135b13eceSDouglas Gregor                      Module, ImportLoc);
138235b13eceSDouglas Gregor   }
138335b13eceSDouglas Gregor 
1384bcfc7d02SDouglas Gregor   // If this module import was due to an inclusion directive, create an
1385bcfc7d02SDouglas Gregor   // implicit import declaration to capture it in the AST.
1386bcfc7d02SDouglas Gregor   if (IsInclusionDirective && hasASTContext()) {
1387bcfc7d02SDouglas Gregor     TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
138872d1aa3cSArgyrios Kyrtzidis     ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
1389bcfc7d02SDouglas Gregor                                                      ImportLoc, Module,
139072d1aa3cSArgyrios Kyrtzidis                                                      Path.back().second);
139172d1aa3cSArgyrios Kyrtzidis     TU->addDecl(ImportD);
139272d1aa3cSArgyrios Kyrtzidis     if (Consumer)
139372d1aa3cSArgyrios Kyrtzidis       Consumer->HandleImplicitImportDecl(ImportD);
1394bcfc7d02SDouglas Gregor   }
1395bcfc7d02SDouglas Gregor 
13961805b8a4SDouglas Gregor   LastModuleImportLoc = ImportLoc;
13977a626570SDouglas Gregor   LastModuleImportResult = ModuleLoadResult(Module, false);
13987a626570SDouglas Gregor   return LastModuleImportResult;
139908142534SDouglas Gregor }
1400c147b0bcSDouglas Gregor 
1401c147b0bcSDouglas Gregor void CompilerInstance::makeModuleVisible(Module *Mod,
1402125df058SArgyrios Kyrtzidis                                          Module::NameVisibilityKind Visibility,
1403fb912657SDouglas Gregor                                          SourceLocation ImportLoc,
1404fb912657SDouglas Gregor                                          bool Complain){
1405fb912657SDouglas Gregor   ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc, Complain);
1406c147b0bcSDouglas Gregor }
1407c147b0bcSDouglas Gregor 
1408