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"
19f988d006SAlp Toker #include "clang/Config/config.h"
208b00dcb0SDavid Blaikie #include "clang/Frontend/ChainedDiagnosticConsumer.h"
214f2bc55dSDaniel Dunbar #include "clang/Frontend/FrontendAction.h"
22faeb1d46SDouglas Gregor #include "clang/Frontend/FrontendActions.h"
23f7093b5aSDaniel Dunbar #include "clang/Frontend/FrontendDiagnostic.h"
242083c32fSDaniel Dunbar #include "clang/Frontend/LogDiagnosticPrinter.h"
254610ea2bSTed Kremenek #include "clang/Frontend/SerializedDiagnosticPrinter.h"
267d75afc5SDaniel Dunbar #include "clang/Frontend/TextDiagnosticPrinter.h"
27aaa148fdSDaniel Dunbar #include "clang/Frontend/Utils.h"
283a02247dSChandler Carruth #include "clang/Frontend/VerifyDiagnosticConsumer.h"
293a02247dSChandler Carruth #include "clang/Lex/HeaderSearch.h"
303a02247dSChandler Carruth #include "clang/Lex/PTHManager.h"
313a02247dSChandler Carruth #include "clang/Lex/Preprocessor.h"
32f7093b5aSDaniel Dunbar #include "clang/Sema/CodeCompleteConsumer.h"
333a02247dSChandler Carruth #include "clang/Sema/Sema.h"
343a02247dSChandler Carruth #include "clang/Serialization/ASTReader.h"
352255f2ceSJohn Thompson #include "clang/Serialization/GlobalModuleIndex.h"
36171b780cSDouglas Gregor #include "llvm/ADT/Statistic.h"
373a02247dSChandler Carruth #include "llvm/Support/CrashRecoveryContext.h"
3871de0b61SRafael Espindola #include "llvm/Support/Errc.h"
393a02247dSChandler Carruth #include "llvm/Support/FileSystem.h"
408aaf4995SMichael J. Spencer #include "llvm/Support/Host.h"
41e212489fSDouglas Gregor #include "llvm/Support/LockFileManager.h"
423a02247dSChandler Carruth #include "llvm/Support/MemoryBuffer.h"
438aaf4995SMichael J. Spencer #include "llvm/Support/Path.h"
448aaf4995SMichael J. Spencer #include "llvm/Support/Program.h"
458aaf4995SMichael J. Spencer #include "llvm/Support/Signals.h"
463a02247dSChandler Carruth #include "llvm/Support/Timer.h"
473a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h"
48527b1c95SDouglas Gregor #include <sys/stat.h>
498a8e554aSRafael Espindola #include <system_error>
5037da327cSDouglas Gregor #include <time.h>
5154a88810SDouglas Gregor 
52636404a3SDaniel Dunbar using namespace clang;
53636404a3SDaniel Dunbar 
542255f2ceSJohn Thompson CompilerInstance::CompilerInstance(bool BuildingModule)
552255f2ceSJohn Thompson   : ModuleLoader(BuildingModule),
5649a2790fSCraig Topper     Invocation(new CompilerInvocation()), ModuleManager(nullptr),
572255f2ceSJohn Thompson     BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false),
582255f2ceSJohn Thompson     ModuleBuildFailed(false) {
59636404a3SDaniel Dunbar }
60636404a3SDaniel Dunbar 
61636404a3SDaniel Dunbar CompilerInstance::~CompilerInstance() {
623c717b45SBenjamin Kramer   assert(OutputFiles.empty() && "Still output files in flight?");
63e922d9bdSDaniel Dunbar }
64e922d9bdSDaniel Dunbar 
6568242254SDaniel Dunbar void CompilerInstance::setInvocation(CompilerInvocation *Value) {
665e14d39aSTed Kremenek   Invocation = Value;
6768242254SDaniel Dunbar }
6868242254SDaniel Dunbar 
69c1bbec85SDouglas Gregor bool CompilerInstance::shouldBuildGlobalModuleIndex() const {
70e060e57bSDouglas Gregor   return (BuildGlobalModuleIndex ||
7111ef0b77SDouglas Gregor           (ModuleManager && ModuleManager->isGlobalIndexUnavailable() &&
7211ef0b77SDouglas Gregor            getFrontendOpts().GenerateGlobalModuleIndex)) &&
73e060e57bSDouglas Gregor          !ModuleBuildFailed;
74c1bbec85SDouglas Gregor }
75c1bbec85SDouglas Gregor 
769c902b55SDavid Blaikie void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) {
777f95d26eSDouglas Gregor   Diagnostics = Value;
78e01dc86dSDaniel Dunbar }
79e01dc86dSDaniel Dunbar 
80e01dc86dSDaniel Dunbar void CompilerInstance::setTarget(TargetInfo *Value) {
815e14d39aSTed Kremenek   Target = Value;
82e01dc86dSDaniel Dunbar }
83e01dc86dSDaniel Dunbar 
84e01dc86dSDaniel Dunbar void CompilerInstance::setFileManager(FileManager *Value) {
855e14d39aSTed Kremenek   FileMgr = Value;
86c8130a74SBen Langmuir   if (Value)
87c8130a74SBen Langmuir     VirtualFileSystem = Value->getVirtualFileSystem();
88c8130a74SBen Langmuir   else
89c8130a74SBen Langmuir     VirtualFileSystem.reset();
90e01dc86dSDaniel Dunbar }
91e01dc86dSDaniel Dunbar 
92e01dc86dSDaniel Dunbar void CompilerInstance::setSourceManager(SourceManager *Value) {
935e14d39aSTed Kremenek   SourceMgr = Value;
94e01dc86dSDaniel Dunbar }
95e01dc86dSDaniel Dunbar 
965e14d39aSTed Kremenek void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; }
97e01dc86dSDaniel Dunbar 
985e14d39aSTed Kremenek void CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; }
99e01dc86dSDaniel Dunbar 
1000e93f017SDouglas Gregor void CompilerInstance::setSema(Sema *S) {
1010e93f017SDouglas Gregor   TheSema.reset(S);
1020e93f017SDouglas Gregor }
1030e93f017SDouglas Gregor 
1046beb6aa8SDavid Blaikie void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) {
1056beb6aa8SDavid Blaikie   Consumer = std::move(Value);
10656d9c293SDaniel Dunbar }
10756d9c293SDaniel Dunbar 
108e01dc86dSDaniel Dunbar void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
109e01dc86dSDaniel Dunbar   CompletionConsumer.reset(Value);
110e01dc86dSDaniel Dunbar }
111e01dc86dSDaniel Dunbar 
1126153581aSDavid Blaikie std::unique_ptr<Sema> CompilerInstance::takeSema() {
1136153581aSDavid Blaikie   return std::move(TheSema);
1146153581aSDavid Blaikie }
1156153581aSDavid Blaikie 
1161b7ed91eSArgyrios Kyrtzidis IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const {
1171b7ed91eSArgyrios Kyrtzidis   return ModuleManager;
1181b7ed91eSArgyrios Kyrtzidis }
1191b7ed91eSArgyrios Kyrtzidis void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) {
1201b7ed91eSArgyrios Kyrtzidis   ModuleManager = Reader;
1211b7ed91eSArgyrios Kyrtzidis }
1221b7ed91eSArgyrios Kyrtzidis 
12386d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector>
12486d1259cSJustin Bogner CompilerInstance::getModuleDepCollector() const {
12586d1259cSJustin Bogner   return ModuleDepCollector;
12686d1259cSJustin Bogner }
12786d1259cSJustin Bogner 
12886d1259cSJustin Bogner void CompilerInstance::setModuleDepCollector(
12986d1259cSJustin Bogner     std::shared_ptr<ModuleDependencyCollector> Collector) {
13086d1259cSJustin Bogner   ModuleDepCollector = Collector;
13186d1259cSJustin Bogner }
13286d1259cSJustin Bogner 
1337d75afc5SDaniel Dunbar // Diagnostics
134811db4eaSDouglas Gregor static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
1357b83306dSDaniel Dunbar                                const CodeGenOptions *CodeGenOpts,
1369c902b55SDavid Blaikie                                DiagnosticsEngine &Diags) {
137dae941a6SRafael Espindola   std::error_code EC;
13811f8a943SDavid Blaikie   std::unique_ptr<raw_ostream> StreamOwner;
1390e62c1ccSChris Lattner   raw_ostream *OS = &llvm::errs();
140811db4eaSDouglas Gregor   if (DiagOpts->DiagnosticLogFile != "-") {
1412083c32fSDaniel Dunbar     // Create the output stream.
14211f8a943SDavid Blaikie     auto FileOS = llvm::make_unique<llvm::raw_fd_ostream>(
143dae941a6SRafael Espindola         DiagOpts->DiagnosticLogFile, EC,
14411f8a943SDavid Blaikie         llvm::sys::fs::F_Append | llvm::sys::fs::F_Text);
145dae941a6SRafael Espindola     if (EC) {
1462083c32fSDaniel Dunbar       Diags.Report(diag::warn_fe_cc_log_diagnostics_failure)
147dae941a6SRafael Espindola           << DiagOpts->DiagnosticLogFile << EC.message();
1482083c32fSDaniel Dunbar     } else {
1492083c32fSDaniel Dunbar       FileOS->SetUnbuffered();
1502083c32fSDaniel Dunbar       FileOS->SetUseAtomicWrites(true);
15111f8a943SDavid Blaikie       OS = FileOS.get();
15211f8a943SDavid Blaikie       StreamOwner = std::move(FileOS);
1532083c32fSDaniel Dunbar     }
1542083c32fSDaniel Dunbar   }
1552083c32fSDaniel Dunbar 
1562083c32fSDaniel Dunbar   // Chain in the diagnostic client which will log the diagnostics.
1577ee25502SDavid Blaikie   auto Logger = llvm::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,
1587ee25502SDavid Blaikie                                                         std::move(StreamOwner));
1597b83306dSDaniel Dunbar   if (CodeGenOpts)
1607b83306dSDaniel Dunbar     Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags);
1617ee25502SDavid Blaikie   assert(Diags.ownsClient());
16241c247a6SAlexander Kornienko   Diags.setClient(
16341c247a6SAlexander Kornienko       new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger)));
1642083c32fSDaniel Dunbar }
1652083c32fSDaniel Dunbar 
166811db4eaSDouglas Gregor static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts,
1674610ea2bSTed Kremenek                                        DiagnosticsEngine &Diags,
1684610ea2bSTed Kremenek                                        StringRef OutputFile) {
1697ee25502SDavid Blaikie   auto SerializedConsumer =
1705a6a2fcdSJustin Bogner       clang::serialized_diags::create(OutputFile, DiagOpts);
1714610ea2bSTed Kremenek 
172254b7dbaSAlexander Kornienko   if (Diags.ownsClient()) {
1737ee25502SDavid Blaikie     Diags.setClient(new ChainedDiagnosticConsumer(
17441c247a6SAlexander Kornienko         Diags.takeClient(), std::move(SerializedConsumer)));
175254b7dbaSAlexander Kornienko   } else {
176254b7dbaSAlexander Kornienko     Diags.setClient(new ChainedDiagnosticConsumer(
1774c0ef379SAlexander Kornienko         Diags.getClient(), std::move(SerializedConsumer)));
178254b7dbaSAlexander Kornienko   }
1794610ea2bSTed Kremenek }
1804610ea2bSTed Kremenek 
181f1b49e23SSean Silva void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client,
18230071ceaSDouglas Gregor                                          bool ShouldOwnClient) {
183f1b49e23SSean Silva   Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client,
18430071ceaSDouglas Gregor                                   ShouldOwnClient, &getCodeGenOpts());
1857d75afc5SDaniel Dunbar }
1867d75afc5SDaniel Dunbar 
187c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine>
188811db4eaSDouglas Gregor CompilerInstance::createDiagnostics(DiagnosticOptions *Opts,
189e2eefaecSDavid Blaikie                                     DiagnosticConsumer *Client,
1902b9b4642SDouglas Gregor                                     bool ShouldOwnClient,
1917b83306dSDaniel Dunbar                                     const CodeGenOptions *CodeGenOpts) {
192c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
193c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticsEngine>
194811db4eaSDouglas Gregor       Diags(new DiagnosticsEngine(DiagID, Opts));
1951b39a2edSDaniel Dunbar 
1967d75afc5SDaniel Dunbar   // Create the diagnostic client for reporting errors or for
1977d75afc5SDaniel Dunbar   // implementing -verify.
198d0e9e3a6SDouglas Gregor   if (Client) {
199d0e9e3a6SDouglas Gregor     Diags->setClient(Client, ShouldOwnClient);
200d0e9e3a6SDouglas Gregor   } else
2012dd19f1dSDouglas Gregor     Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));
20250ec0da0SDaniel Dunbar 
20350ec0da0SDaniel Dunbar   // Chain in -verify checker, if requested.
204811db4eaSDouglas Gregor   if (Opts->VerifyDiagnostics)
20569609dceSDavid Blaikie     Diags->setClient(new VerifyDiagnosticConsumer(*Diags));
2067d75afc5SDaniel Dunbar 
2072083c32fSDaniel Dunbar   // Chain in -diagnostic-log-file dumper, if requested.
208811db4eaSDouglas Gregor   if (!Opts->DiagnosticLogFile.empty())
2097b83306dSDaniel Dunbar     SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags);
2102083c32fSDaniel 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() {
224c8130a74SBen Langmuir   if (!hasVirtualFileSystem()) {
225c8130a74SBen Langmuir     // TODO: choose the virtual file system based on the CompilerInvocation.
226c8130a74SBen Langmuir     setVirtualFileSystem(vfs::getRealFileSystem());
227c8130a74SBen Langmuir   }
228c8130a74SBen Langmuir   FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem);
229546a676aSDaniel Dunbar }
230546a676aSDaniel Dunbar 
2317d75afc5SDaniel Dunbar // Source Manager
2327d75afc5SDaniel Dunbar 
2335159f616SChris Lattner void CompilerInstance::createSourceManager(FileManager &FileMgr) {
2345e14d39aSTed Kremenek   SourceMgr = new SourceManager(getDiagnostics(), FileMgr);
235546a676aSDaniel Dunbar }
236aaa148fdSDaniel Dunbar 
237c358000eSAlp Toker // Initialize the remapping of files to alternative contents, e.g.,
238c358000eSAlp Toker // those specified through other files.
239c358000eSAlp Toker static void InitializeFileRemapping(DiagnosticsEngine &Diags,
240c358000eSAlp Toker                                     SourceManager &SourceMgr,
241c358000eSAlp Toker                                     FileManager &FileMgr,
242c358000eSAlp Toker                                     const PreprocessorOptions &InitOpts) {
243c358000eSAlp Toker   // Remap files in the source manager (with buffers).
2441b070d25SAlp Toker   for (const auto &RB : InitOpts.RemappedFileBuffers) {
245c358000eSAlp Toker     // Create the file entry for the file that we're mapping from.
246c358000eSAlp Toker     const FileEntry *FromFile =
2471b070d25SAlp Toker         FileMgr.getVirtualFile(RB.first, RB.second->getBufferSize(), 0);
248c358000eSAlp Toker     if (!FromFile) {
2491b070d25SAlp Toker       Diags.Report(diag::err_fe_remap_missing_from_file) << RB.first;
250c358000eSAlp Toker       if (!InitOpts.RetainRemappedFileBuffers)
2511b070d25SAlp Toker         delete RB.second;
252c358000eSAlp Toker       continue;
253c358000eSAlp Toker     }
254c358000eSAlp Toker 
255c358000eSAlp Toker     // Override the contents of the "from" file with the contents of
256c358000eSAlp Toker     // the "to" file.
2571b070d25SAlp Toker     SourceMgr.overrideFileContents(FromFile, RB.second,
258c358000eSAlp Toker                                    InitOpts.RetainRemappedFileBuffers);
259c358000eSAlp Toker   }
260c358000eSAlp Toker 
261c358000eSAlp Toker   // Remap files in the source manager (with other files).
2621b070d25SAlp Toker   for (const auto &RF : InitOpts.RemappedFiles) {
263c358000eSAlp Toker     // Find the file that we're mapping to.
2641b070d25SAlp Toker     const FileEntry *ToFile = FileMgr.getFile(RF.second);
265c358000eSAlp Toker     if (!ToFile) {
2661b070d25SAlp Toker       Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
267c358000eSAlp Toker       continue;
268c358000eSAlp Toker     }
269c358000eSAlp Toker 
270c358000eSAlp Toker     // Create the file entry for the file that we're mapping from.
271c358000eSAlp Toker     const FileEntry *FromFile =
2721b070d25SAlp Toker         FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0);
273c358000eSAlp Toker     if (!FromFile) {
2741b070d25SAlp Toker       Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first;
275c358000eSAlp Toker       continue;
276c358000eSAlp Toker     }
277c358000eSAlp Toker 
278c358000eSAlp Toker     // Override the contents of the "from" file with the contents of
279c358000eSAlp Toker     // the "to" file.
280c358000eSAlp Toker     SourceMgr.overrideFileContents(FromFile, ToFile);
281c358000eSAlp Toker   }
282c358000eSAlp Toker 
283c358000eSAlp Toker   SourceMgr.setOverridenFilesKeepOriginalName(
284c358000eSAlp Toker       InitOpts.RemappedFilesKeepOriginalName);
285c358000eSAlp Toker }
286c358000eSAlp Toker 
2877d75afc5SDaniel Dunbar // Preprocessor
2887d75afc5SDaniel Dunbar 
289e1974dcdSArgyrios Kyrtzidis void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
29008142534SDouglas Gregor   const PreprocessorOptions &PPOpts = getPreprocessorOpts();
291aaa148fdSDaniel Dunbar 
292aaa148fdSDaniel Dunbar   // Create a PTH manager if we are using some form of a token cache.
29349a2790fSCraig Topper   PTHManager *PTHMgr = nullptr;
294d6ea9028SDaniel Dunbar   if (!PPOpts.TokenCache.empty())
29508142534SDouglas Gregor     PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics());
296aaa148fdSDaniel Dunbar 
297aaa148fdSDaniel Dunbar   // Create the Preprocessor.
298b85b9ccbSDouglas Gregor   HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(),
2991f76c4e8SManuel Klimek                                               getSourceManager(),
3001fb5c3a6SDouglas Gregor                                               getDiagnostics(),
30189929282SDouglas Gregor                                               getLangOpts(),
30289929282SDouglas Gregor                                               &getTarget());
3039663780eSAlp Toker   PP = new Preprocessor(&getPreprocessorOpts(), getDiagnostics(), getLangOpts(),
30408142534SDouglas Gregor                         getSourceManager(), *HeaderInfo, *this, PTHMgr,
3059663780eSAlp Toker                         /*OwnsHeaderSearch=*/true, TUKind);
3061ae02f68SAlp Toker   PP->Initialize(getTarget());
307aaa148fdSDaniel Dunbar 
308aaa148fdSDaniel Dunbar   // Note that this is different then passing PTHMgr to Preprocessor's ctor.
309aaa148fdSDaniel Dunbar   // That argument is used as the IdentifierInfoLookup argument to
310aaa148fdSDaniel Dunbar   // IdentifierTable's ctor.
311aaa148fdSDaniel Dunbar   if (PTHMgr) {
31208142534SDouglas Gregor     PTHMgr->setPreprocessor(&*PP);
313aaa148fdSDaniel Dunbar     PP->setPTHManager(PTHMgr);
314aaa148fdSDaniel Dunbar   }
315aaa148fdSDaniel Dunbar 
3167f6d60dcSDouglas Gregor   if (PPOpts.DetailedRecord)
317f3d587eaSArgyrios Kyrtzidis     PP->createPreprocessingRecord();
3187f6d60dcSDouglas Gregor 
319c358000eSAlp Toker   // Apply remappings to the source manager.
320c358000eSAlp Toker   InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(),
321c358000eSAlp Toker                           PP->getFileManager(), PPOpts);
322c358000eSAlp Toker 
323c358000eSAlp Toker   // Predefine macros and configure the preprocessor.
324c358000eSAlp Toker   InitializePreprocessor(*PP, PPOpts, getFrontendOpts());
325c358000eSAlp Toker 
326c358000eSAlp Toker   // Initialize the header search object.
327c358000eSAlp Toker   ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(),
328c358000eSAlp Toker                            PP->getLangOpts(), PP->getTargetInfo().getTriple());
329aaa148fdSDaniel Dunbar 
33017441589SJordan Rose   PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP);
33117441589SJordan Rose 
332bd0b651bSArgyrios Kyrtzidis   PP->getHeaderSearchInfo().setModuleCachePath(getSpecificModuleCachePath());
3331735f4e7SDouglas Gregor 
334aaa148fdSDaniel Dunbar   // Handle generating dependencies, if requested.
33508142534SDouglas Gregor   const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
336aaa148fdSDaniel Dunbar   if (!DepOpts.OutputFile.empty())
337cb69b57bSBen Langmuir     TheDependencyFileGenerator.reset(
338cb69b57bSBen Langmuir         DependencyFileGenerator::CreateAndAttachToPreprocessor(*PP, DepOpts));
3392e129659SDouglas Gregor   if (!DepOpts.DOTOutputFile.empty())
3402e129659SDouglas Gregor     AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,
34183d46be3SDouglas Gregor                              getHeaderSearchOpts().Sysroot);
34283d46be3SDouglas Gregor 
34333c8090aSBen Langmuir   for (auto &Listener : DependencyCollectors)
34433c8090aSBen Langmuir     Listener->attachToPreprocessor(*PP);
34533c8090aSBen Langmuir 
34686d1259cSJustin Bogner   // If we don't have a collector, but we are collecting module dependencies,
34786d1259cSJustin Bogner   // then we're the top level compiler instance and need to create one.
34886d1259cSJustin Bogner   if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty())
34986d1259cSJustin Bogner     ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
35086d1259cSJustin Bogner         DepOpts.ModuleDependencyOutputDir);
351aaa148fdSDaniel Dunbar 
35227734fdbSDaniel Dunbar   // Handle generating header include information, if requested.
35327734fdbSDaniel Dunbar   if (DepOpts.ShowHeaderIncludes)
35427734fdbSDaniel Dunbar     AttachHeaderIncludeGen(*PP);
3551af1d275SDaniel Dunbar   if (!DepOpts.HeaderIncludeOutputFile.empty()) {
3560e62c1ccSChris Lattner     StringRef OutputPath = DepOpts.HeaderIncludeOutputFile;
3571af1d275SDaniel Dunbar     if (OutputPath == "-")
3581af1d275SDaniel Dunbar       OutputPath = "";
359fe908a80SDaniel Dunbar     AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath,
360fe908a80SDaniel Dunbar                            /*ShowDepth=*/false);
3610fd6207dSHans Wennborg   }
3620fd6207dSHans Wennborg 
3630fd6207dSHans Wennborg   if (DepOpts.PrintShowIncludes) {
3640fd6207dSHans Wennborg     AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/false, /*OutputPath=*/"",
3650fd6207dSHans Wennborg                            /*ShowDepth=*/true, /*MSStyle=*/true);
3661af1d275SDaniel Dunbar   }
367aaa148fdSDaniel Dunbar }
368df3e30c4SDaniel Dunbar 
369bd0b651bSArgyrios Kyrtzidis std::string CompilerInstance::getSpecificModuleCachePath() {
370bd0b651bSArgyrios Kyrtzidis   // Set up the module path, including the hash for the
371bd0b651bSArgyrios Kyrtzidis   // module-creation options.
372bd0b651bSArgyrios Kyrtzidis   SmallString<256> SpecificModuleCache(
373bd0b651bSArgyrios Kyrtzidis                            getHeaderSearchOpts().ModuleCachePath);
374bd0b651bSArgyrios Kyrtzidis   if (!getHeaderSearchOpts().DisableModuleHash)
375bd0b651bSArgyrios Kyrtzidis     llvm::sys::path::append(SpecificModuleCache,
376bd0b651bSArgyrios Kyrtzidis                             getInvocation().getModuleHash());
377bd0b651bSArgyrios Kyrtzidis   return SpecificModuleCache.str();
378bd0b651bSArgyrios Kyrtzidis }
379bd0b651bSArgyrios Kyrtzidis 
380df3e30c4SDaniel Dunbar // ASTContext
381df3e30c4SDaniel Dunbar 
382df3e30c4SDaniel Dunbar void CompilerInstance::createASTContext() {
383df3e30c4SDaniel Dunbar   Preprocessor &PP = getPreprocessor();
3845e14d39aSTed Kremenek   Context = new ASTContext(getLangOpts(), PP.getSourceManager(),
38508043437SAlp Toker                            PP.getIdentifierTable(), PP.getSelectorTable(),
38608043437SAlp Toker                            PP.getBuiltinInfo());
38708043437SAlp Toker   Context->InitBuiltinTypes(getTarget());
388df3e30c4SDaniel Dunbar }
389599313efSDaniel Dunbar 
390599313efSDaniel Dunbar // ExternalASTSource
391599313efSDaniel Dunbar 
392824285ecSNico Weber void CompilerInstance::createPCHExternalASTSource(
393824285ecSNico Weber     StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors,
394824285ecSNico Weber     void *DeserializationListener, bool OwnDeserializationListener) {
395009e7f20SSebastian Redl   bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
3964eca9b93SRichard Smith   ModuleManager = createPCHExternalASTSource(
397824285ecSNico Weber       Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,
398824285ecSNico Weber       AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(),
399824285ecSNico Weber       DeserializationListener, OwnDeserializationListener, Preamble,
4001b7ed91eSArgyrios Kyrtzidis       getFrontendOpts().UseGlobalModuleIndex);
401599313efSDaniel Dunbar }
402599313efSDaniel Dunbar 
4034eca9b93SRichard Smith IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
404824285ecSNico Weber     StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,
405824285ecSNico Weber     bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
406824285ecSNico Weber     void *DeserializationListener, bool OwnDeserializationListener,
407824285ecSNico Weber     bool Preamble, bool UseGlobalModuleIndex) {
408dcf73861SBen Langmuir   HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
409dcf73861SBen Langmuir 
4104eca9b93SRichard Smith   IntrusiveRefCntPtr<ASTReader> Reader(
4114eca9b93SRichard Smith       new ASTReader(PP, Context, Sysroot.empty() ? "" : Sysroot.c_str(),
4124eca9b93SRichard Smith                     DisablePCHValidation, AllowPCHWithCompilerErrors,
4133d4417c7SBen Langmuir                     /*AllowConfigurationMismatch*/ false,
4144eca9b93SRichard Smith                     HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex));
4154eca9b93SRichard Smith 
4164eca9b93SRichard Smith   // We need the external source to be set up before we read the AST, because
4174eca9b93SRichard Smith   // eagerly-deserialized declarations may use it.
4184eca9b93SRichard Smith   Context.setExternalSource(Reader.get());
419599313efSDaniel Dunbar 
42007a89a83SSebastian Redl   Reader->setDeserializationListener(
421824285ecSNico Weber       static_cast<ASTDeserializationListener *>(DeserializationListener),
422824285ecSNico Weber       /*TakeOwnership=*/OwnDeserializationListener);
423009e7f20SSebastian Redl   switch (Reader->ReadAST(Path,
424a6895d8aSDouglas Gregor                           Preamble ? serialization::MK_Preamble
4254b29c16eSDouglas Gregor                                    : serialization::MK_PCH,
4262ec29367SArgyrios Kyrtzidis                           SourceLocation(),
4273d4417c7SBen Langmuir                           ASTReader::ARR_None)) {
4282c499f65SSebastian Redl   case ASTReader::Success:
429599313efSDaniel Dunbar     // Set the predefines buffer as suggested by the PCH reader. Typically, the
430599313efSDaniel Dunbar     // predefines buffer will be empty.
431599313efSDaniel Dunbar     PP.setPredefines(Reader->getSuggestedPredefines());
4324eca9b93SRichard Smith     return Reader;
433599313efSDaniel Dunbar 
4342c499f65SSebastian Redl   case ASTReader::Failure:
435599313efSDaniel Dunbar     // Unrecoverable failure: don't even try to process the input file.
436599313efSDaniel Dunbar     break;
437599313efSDaniel Dunbar 
4387029ce1aSDouglas Gregor   case ASTReader::Missing:
439c9ad5fb6SDouglas Gregor   case ASTReader::OutOfDate:
440c9ad5fb6SDouglas Gregor   case ASTReader::VersionMismatch:
441c9ad5fb6SDouglas Gregor   case ASTReader::ConfigurationMismatch:
442c9ad5fb6SDouglas Gregor   case ASTReader::HadErrors:
443599313efSDaniel Dunbar     // No suitable PCH file could be found. Return an error.
444599313efSDaniel Dunbar     break;
445599313efSDaniel Dunbar   }
446599313efSDaniel Dunbar 
4474eca9b93SRichard Smith   Context.setExternalSource(nullptr);
44849a2790fSCraig Topper   return nullptr;
449599313efSDaniel Dunbar }
450f7093b5aSDaniel Dunbar 
451f7093b5aSDaniel Dunbar // Code Completion
452f7093b5aSDaniel Dunbar 
4538e984da8SDouglas Gregor static bool EnableCodeCompletion(Preprocessor &PP,
4548e984da8SDouglas Gregor                                  const std::string &Filename,
4558e984da8SDouglas Gregor                                  unsigned Line,
4568e984da8SDouglas Gregor                                  unsigned Column) {
4578e984da8SDouglas Gregor   // Tell the source manager to chop off the given file at a specific
4588e984da8SDouglas Gregor   // line and column.
4595159f616SChris Lattner   const FileEntry *Entry = PP.getFileManager().getFile(Filename);
4608e984da8SDouglas Gregor   if (!Entry) {
4618e984da8SDouglas Gregor     PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
4628e984da8SDouglas Gregor       << Filename;
4638e984da8SDouglas Gregor     return true;
4648e984da8SDouglas Gregor   }
4658e984da8SDouglas Gregor 
4668e984da8SDouglas Gregor   // Truncate the named file at the given line/column.
4678e984da8SDouglas Gregor   PP.SetCodeCompletionPoint(Entry, Line, Column);
4688e984da8SDouglas Gregor   return false;
4698e984da8SDouglas Gregor }
4708e984da8SDouglas Gregor 
471f7093b5aSDaniel Dunbar void CompilerInstance::createCodeCompletionConsumer() {
472f7093b5aSDaniel Dunbar   const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt;
4738e984da8SDouglas Gregor   if (!CompletionConsumer) {
4742fca3c2cSErik Verbruggen     setCodeCompletionConsumer(
475f7093b5aSDaniel Dunbar       createCodeCompletionConsumer(getPreprocessor(),
476f7093b5aSDaniel Dunbar                                    Loc.FileName, Loc.Line, Loc.Column,
4773292d06aSDmitri Gribenko                                    getFrontendOpts().CodeCompleteOpts,
478f7093b5aSDaniel Dunbar                                    llvm::outs()));
47900a0cf70SDouglas Gregor     if (!CompletionConsumer)
48000a0cf70SDouglas Gregor       return;
4818e984da8SDouglas Gregor   } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName,
4828e984da8SDouglas Gregor                                   Loc.Line, Loc.Column)) {
48349a2790fSCraig Topper     setCodeCompletionConsumer(nullptr);
4848e984da8SDouglas Gregor     return;
4858e984da8SDouglas Gregor   }
486f09935f1SDouglas Gregor 
487f09935f1SDouglas Gregor   if (CompletionConsumer->isOutputBinary() &&
488a3346d87SRafael Espindola       llvm::sys::ChangeStdoutToBinary()) {
489f09935f1SDouglas Gregor     getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary);
49049a2790fSCraig Topper     setCodeCompletionConsumer(nullptr);
491f09935f1SDouglas Gregor   }
492f7093b5aSDaniel Dunbar }
493f7093b5aSDaniel Dunbar 
4945505dff8SKovarththanan Rajaratnam void CompilerInstance::createFrontendTimer() {
4955505dff8SKovarththanan Rajaratnam   FrontendTimer.reset(new llvm::Timer("Clang front-end timer"));
4965505dff8SKovarththanan Rajaratnam }
4975505dff8SKovarththanan Rajaratnam 
498f7093b5aSDaniel Dunbar CodeCompleteConsumer *
499f7093b5aSDaniel Dunbar CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP,
500f7093b5aSDaniel Dunbar                                                const std::string &Filename,
501f7093b5aSDaniel Dunbar                                                unsigned Line,
502f7093b5aSDaniel Dunbar                                                unsigned Column,
5033292d06aSDmitri Gribenko                                                const CodeCompleteOptions &Opts,
5040e62c1ccSChris Lattner                                                raw_ostream &OS) {
5058e984da8SDouglas Gregor   if (EnableCodeCompletion(PP, Filename, Line, Column))
50649a2790fSCraig Topper     return nullptr;
507f7093b5aSDaniel Dunbar 
508f7093b5aSDaniel Dunbar   // Set up the creation routine for code-completion.
5093292d06aSDmitri Gribenko   return new PrintingCodeCompleteConsumer(Opts, OS);
510f7093b5aSDaniel Dunbar }
511566eeb2dSDaniel Dunbar 
51269f74f80SDouglas Gregor void CompilerInstance::createSema(TranslationUnitKind TUKind,
5130e93f017SDouglas Gregor                                   CodeCompleteConsumer *CompletionConsumer) {
5140e93f017SDouglas Gregor   TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(),
51569f74f80SDouglas Gregor                          TUKind, CompletionConsumer));
5160e93f017SDouglas Gregor }
5170e93f017SDouglas Gregor 
518566eeb2dSDaniel Dunbar // Output Files
519566eeb2dSDaniel Dunbar 
52069f3528cSNAKAMURA Takumi void CompilerInstance::addOutputFile(const OutputFile &OutFile) {
521d0599970SArgyrios Kyrtzidis   assert(OutFile.OS && "Attempt to add empty stream to output list!");
52269f3528cSNAKAMURA Takumi   OutputFiles.push_back(OutFile);
523566eeb2dSDaniel Dunbar }
524566eeb2dSDaniel Dunbar 
5251c558cd7SKovarththanan Rajaratnam void CompilerInstance::clearOutputFiles(bool EraseFiles) {
526d0599970SArgyrios Kyrtzidis   for (std::list<OutputFile>::iterator
527566eeb2dSDaniel Dunbar          it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) {
52869f3528cSNAKAMURA Takumi     delete it->OS;
529d0599970SArgyrios Kyrtzidis     if (!it->TempFilename.empty()) {
530b5c356a4SAnders Carlsson       if (EraseFiles) {
5312a008784SRafael Espindola         llvm::sys::fs::remove(it->TempFilename);
532b5c356a4SAnders Carlsson       } else {
5332c1dd271SDylan Noblesmith         SmallString<128> NewOutFile(it->Filename);
534b5c356a4SAnders Carlsson 
53571731d6bSArgyrios Kyrtzidis         // If '-working-directory' was passed, the output filename should be
53671731d6bSArgyrios Kyrtzidis         // relative to that.
5379ba8fb1eSAnders Carlsson         FileMgr->FixupRelativePath(NewOutFile);
538c080917eSRafael Espindola         if (std::error_code ec =
539c080917eSRafael Espindola                 llvm::sys::fs::rename(it->TempFilename, NewOutFile.str())) {
5403ef9c447SManuel Klimek           getDiagnostics().Report(diag::err_unable_to_rename_temp)
541b5c356a4SAnders Carlsson             << it->TempFilename << it->Filename << ec.message();
542b5c356a4SAnders Carlsson 
5432a008784SRafael Espindola           llvm::sys::fs::remove(it->TempFilename);
544d0599970SArgyrios Kyrtzidis         }
545d0599970SArgyrios Kyrtzidis       }
546d0599970SArgyrios Kyrtzidis     } else if (!it->Filename.empty() && EraseFiles)
547399ab33aSRafael Espindola       llvm::sys::fs::remove(it->Filename);
548d0599970SArgyrios Kyrtzidis 
549566eeb2dSDaniel Dunbar   }
550566eeb2dSDaniel Dunbar   OutputFiles.clear();
551566eeb2dSDaniel Dunbar }
552566eeb2dSDaniel Dunbar 
553420b0f1bSDaniel Dunbar llvm::raw_fd_ostream *
554420b0f1bSDaniel Dunbar CompilerInstance::createDefaultOutputFile(bool Binary,
5550e62c1ccSChris Lattner                                           StringRef InFile,
5560e62c1ccSChris Lattner                                           StringRef Extension) {
557420b0f1bSDaniel Dunbar   return createOutputFile(getFrontendOpts().OutputFile, Binary,
558ae77b3dfSDaniel Dunbar                           /*RemoveFileOnSignal=*/true, InFile, Extension,
559ae77b3dfSDaniel Dunbar                           /*UseTemporary=*/true);
560420b0f1bSDaniel Dunbar }
561420b0f1bSDaniel Dunbar 
562ea04672cSAlp Toker llvm::raw_null_ostream *CompilerInstance::createNullOutputFile() {
56369f3528cSNAKAMURA Takumi   llvm::raw_null_ostream *OS = new llvm::raw_null_ostream();
56469f3528cSNAKAMURA Takumi   addOutputFile(OutputFile("", "", OS));
56569f3528cSNAKAMURA Takumi   return OS;
566ea04672cSAlp Toker }
567ea04672cSAlp Toker 
568420b0f1bSDaniel Dunbar llvm::raw_fd_ostream *
5690e62c1ccSChris Lattner CompilerInstance::createOutputFile(StringRef OutputPath,
570e326f9bbSDaniel Dunbar                                    bool Binary, bool RemoveFileOnSignal,
5710e62c1ccSChris Lattner                                    StringRef InFile,
57208a2bfd2SArgyrios Kyrtzidis                                    StringRef Extension,
573b9c62c07SDaniel Dunbar                                    bool UseTemporary,
574b9c62c07SDaniel Dunbar                                    bool CreateMissingDirectories) {
575dae941a6SRafael Espindola   std::string OutputPathName, TempPathName;
576dae941a6SRafael Espindola   std::error_code EC;
577dae941a6SRafael Espindola   llvm::raw_fd_ostream *OS = createOutputFile(
578dae941a6SRafael Espindola       OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension,
579dae941a6SRafael Espindola       UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName);
580420b0f1bSDaniel Dunbar   if (!OS) {
581dae941a6SRafael Espindola     getDiagnostics().Report(diag::err_fe_unable_to_open_output) << OutputPath
582dae941a6SRafael Espindola                                                                 << EC.message();
58349a2790fSCraig Topper     return nullptr;
584420b0f1bSDaniel Dunbar   }
585420b0f1bSDaniel Dunbar 
586420b0f1bSDaniel Dunbar   // Add the output file -- but don't try to remove "-", since this means we are
587420b0f1bSDaniel Dunbar   // using stdin.
588d0599970SArgyrios Kyrtzidis   addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "",
58969f3528cSNAKAMURA Takumi                 TempPathName, OS));
590420b0f1bSDaniel Dunbar 
59169f3528cSNAKAMURA Takumi   return OS;
592420b0f1bSDaniel Dunbar }
593420b0f1bSDaniel Dunbar 
594dae941a6SRafael Espindola llvm::raw_fd_ostream *CompilerInstance::createOutputFile(
595dae941a6SRafael Espindola     StringRef OutputPath, std::error_code &Error, bool Binary,
596dae941a6SRafael Espindola     bool RemoveFileOnSignal, StringRef InFile, StringRef Extension,
597dae941a6SRafael Espindola     bool UseTemporary, bool CreateMissingDirectories,
598dae941a6SRafael Espindola     std::string *ResultPathName, std::string *TempPathName) {
599b9c62c07SDaniel Dunbar   assert((!CreateMissingDirectories || UseTemporary) &&
600b9c62c07SDaniel Dunbar          "CreateMissingDirectories is only allowed when using temporary files");
601b9c62c07SDaniel Dunbar 
602d0599970SArgyrios Kyrtzidis   std::string OutFile, TempFile;
603420b0f1bSDaniel Dunbar   if (!OutputPath.empty()) {
604420b0f1bSDaniel Dunbar     OutFile = OutputPath;
605420b0f1bSDaniel Dunbar   } else if (InFile == "-") {
606420b0f1bSDaniel Dunbar     OutFile = "-";
607420b0f1bSDaniel Dunbar   } else if (!Extension.empty()) {
608399ab33aSRafael Espindola     SmallString<128> Path(InFile);
609399ab33aSRafael Espindola     llvm::sys::path::replace_extension(Path, Extension);
610420b0f1bSDaniel Dunbar     OutFile = Path.str();
611420b0f1bSDaniel Dunbar   } else {
612420b0f1bSDaniel Dunbar     OutFile = "-";
613420b0f1bSDaniel Dunbar   }
614420b0f1bSDaniel Dunbar 
615b8984329SAhmed Charles   std::unique_ptr<llvm::raw_fd_ostream> OS;
61608a2bfd2SArgyrios Kyrtzidis   std::string OSFile;
61708a2bfd2SArgyrios Kyrtzidis 
61873c23a71SRafael Espindola   if (UseTemporary) {
61973c23a71SRafael Espindola     if (OutFile == "-")
62073c23a71SRafael Espindola       UseTemporary = false;
62173c23a71SRafael Espindola     else {
62273c23a71SRafael Espindola       llvm::sys::fs::file_status Status;
62373c23a71SRafael Espindola       llvm::sys::fs::status(OutputPath, Status);
62473c23a71SRafael Espindola       if (llvm::sys::fs::exists(Status)) {
62573c23a71SRafael Espindola         // Fail early if we can't write to the final destination.
62673c23a71SRafael Espindola         if (!llvm::sys::fs::can_write(OutputPath))
62749a2790fSCraig Topper           return nullptr;
62873c23a71SRafael Espindola 
62973c23a71SRafael Espindola         // Don't use a temporary if the output is a special file. This handles
63073c23a71SRafael Espindola         // things like '-o /dev/null'
63173c23a71SRafael Espindola         if (!llvm::sys::fs::is_regular_file(Status))
63273c23a71SRafael Espindola           UseTemporary = false;
63373c23a71SRafael Espindola       }
63473c23a71SRafael Espindola     }
63573c23a71SRafael Espindola   }
63673c23a71SRafael Espindola 
63773c23a71SRafael Espindola   if (UseTemporary) {
638d0599970SArgyrios Kyrtzidis     // Create a temporary file.
6392c1dd271SDylan Noblesmith     SmallString<128> TempPath;
64008a2bfd2SArgyrios Kyrtzidis     TempPath = OutFile;
64108a2bfd2SArgyrios Kyrtzidis     TempPath += "-%%%%%%%%";
64208a2bfd2SArgyrios Kyrtzidis     int fd;
643c080917eSRafael Espindola     std::error_code EC =
64418627115SRafael Espindola         llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath);
645157f34bdSRafael Espindola 
646157f34bdSRafael Espindola     if (CreateMissingDirectories &&
64771de0b61SRafael Espindola         EC == llvm::errc::no_such_file_or_directory) {
648157f34bdSRafael Espindola       StringRef Parent = llvm::sys::path::parent_path(OutputPath);
649157f34bdSRafael Espindola       EC = llvm::sys::fs::create_directories(Parent);
650157f34bdSRafael Espindola       if (!EC) {
65118627115SRafael Espindola         EC = llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath);
652157f34bdSRafael Espindola       }
653157f34bdSRafael Espindola     }
654157f34bdSRafael Espindola 
655157f34bdSRafael Espindola     if (!EC) {
65669f3528cSNAKAMURA Takumi       OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true));
65708a2bfd2SArgyrios Kyrtzidis       OSFile = TempFile = TempPath.str();
65808a2bfd2SArgyrios Kyrtzidis     }
65973c23a71SRafael Espindola     // If we failed to create the temporary, fallback to writing to the file
66073c23a71SRafael Espindola     // directly. This handles the corner case where we cannot write to the
66173c23a71SRafael Espindola     // directory, but can write to the file.
662d0599970SArgyrios Kyrtzidis   }
663d0599970SArgyrios Kyrtzidis 
66408a2bfd2SArgyrios Kyrtzidis   if (!OS) {
66508a2bfd2SArgyrios Kyrtzidis     OSFile = OutFile;
66669f3528cSNAKAMURA Takumi     OS.reset(new llvm::raw_fd_ostream(
667dae941a6SRafael Espindola         OSFile, Error,
66869f3528cSNAKAMURA Takumi         (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text)));
669dae941a6SRafael Espindola     if (Error)
67049a2790fSCraig Topper       return nullptr;
67108a2bfd2SArgyrios Kyrtzidis   }
672420b0f1bSDaniel Dunbar 
673d0599970SArgyrios Kyrtzidis   // Make sure the out stream file gets removed if we crash.
674e326f9bbSDaniel Dunbar   if (RemoveFileOnSignal)
67518556de3SRafael Espindola     llvm::sys::RemoveFileOnSignal(OSFile);
676d0599970SArgyrios Kyrtzidis 
677420b0f1bSDaniel Dunbar   if (ResultPathName)
678420b0f1bSDaniel Dunbar     *ResultPathName = OutFile;
679d0599970SArgyrios Kyrtzidis   if (TempPathName)
680d0599970SArgyrios Kyrtzidis     *TempPathName = TempFile;
681420b0f1bSDaniel Dunbar 
68269f3528cSNAKAMURA Takumi   return OS.release();
683420b0f1bSDaniel Dunbar }
684409e890fSDaniel Dunbar 
685409e890fSDaniel Dunbar // Initialization Utilities
686409e890fSDaniel Dunbar 
6871b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){
6881b3240b0SArgyrios Kyrtzidis   return InitializeSourceManager(Input, getDiagnostics(),
689a686e1b0SDouglas Gregor                                  getFileManager(), getSourceManager(),
690a686e1b0SDouglas Gregor                                  getFrontendOpts());
691409e890fSDaniel Dunbar }
692409e890fSDaniel Dunbar 
6931b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input,
6949c902b55SDavid Blaikie                                                DiagnosticsEngine &Diags,
695409e890fSDaniel Dunbar                                                FileManager &FileMgr,
696409e890fSDaniel Dunbar                                                SourceManager &SourceMgr,
697409e890fSDaniel Dunbar                                                const FrontendOptions &Opts) {
6981b3240b0SArgyrios Kyrtzidis   SrcMgr::CharacteristicKind
699873c8583SArgyrios Kyrtzidis     Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
7001b3240b0SArgyrios Kyrtzidis 
7016566e23eSArgyrios Kyrtzidis   if (Input.isBuffer()) {
70250a5f97eSDavid Blaikie     SourceMgr.setMainFileID(SourceMgr.createFileID(
70350a5f97eSDavid Blaikie         std::unique_ptr<llvm::MemoryBuffer>(Input.getBuffer()), Kind));
7046566e23eSArgyrios Kyrtzidis     assert(!SourceMgr.getMainFileID().isInvalid() &&
7056566e23eSArgyrios Kyrtzidis            "Couldn't establish MainFileID!");
7066566e23eSArgyrios Kyrtzidis     return true;
7076566e23eSArgyrios Kyrtzidis   }
7086566e23eSArgyrios Kyrtzidis 
7096566e23eSArgyrios Kyrtzidis   StringRef InputFile = Input.getFile();
7106566e23eSArgyrios Kyrtzidis 
7117c06d866SArgyrios Kyrtzidis   // Figure out where to get and map in the main file.
7127c06d866SArgyrios Kyrtzidis   if (InputFile != "-") {
7133841fa38SBenjamin Kramer     const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true);
71452765215SDan Gohman     if (!File) {
715409e890fSDaniel Dunbar       Diags.Report(diag::err_fe_error_reading) << InputFile;
716409e890fSDaniel Dunbar       return false;
717409e890fSDaniel Dunbar     }
718e2951f48SDaniel Dunbar 
719e2951f48SDaniel Dunbar     // The natural SourceManager infrastructure can't currently handle named
720e2951f48SDaniel Dunbar     // pipes, but we would at least like to accept them for the main
7213841fa38SBenjamin Kramer     // file. Detect them here, read them with the volatile flag so FileMgr will
7223841fa38SBenjamin Kramer     // pick up the correct size, and simply override their contents as we do for
7233841fa38SBenjamin Kramer     // STDIN.
724e2951f48SDaniel Dunbar     if (File->isNamedPipe()) {
725a885796dSBenjamin Kramer       auto MB = FileMgr.getBufferForFile(File, /*isVolatile=*/true);
726a885796dSBenjamin Kramer       if (MB) {
727db0745abSDaniel Dunbar         // Create a new virtual file that will have the correct size.
728a885796dSBenjamin Kramer         File = FileMgr.getVirtualFile(InputFile, (*MB)->getBufferSize(), 0);
729a885796dSBenjamin Kramer         SourceMgr.overrideFileContents(File, std::move(*MB));
7303841fa38SBenjamin Kramer       } else {
731a885796dSBenjamin Kramer         Diags.Report(diag::err_cannot_open_file) << InputFile
732a885796dSBenjamin Kramer                                                  << MB.getError().message();
7333841fa38SBenjamin Kramer         return false;
7343841fa38SBenjamin Kramer       }
735e2951f48SDaniel Dunbar     }
736db0745abSDaniel Dunbar 
737b671e34cSAlp Toker     SourceMgr.setMainFileID(
738b671e34cSAlp Toker         SourceMgr.createFileID(File, SourceLocation(), Kind));
739409e890fSDaniel Dunbar   } else {
7402d2b420aSRafael Espindola     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> SBOrErr =
7412d2b420aSRafael Espindola         llvm::MemoryBuffer::getSTDIN();
7422d2b420aSRafael Espindola     if (std::error_code EC = SBOrErr.getError()) {
7432d2b420aSRafael Espindola       Diags.Report(diag::err_fe_error_reading_stdin) << EC.message();
744409e890fSDaniel Dunbar       return false;
745409e890fSDaniel Dunbar     }
7462d2b420aSRafael Espindola     std::unique_ptr<llvm::MemoryBuffer> SB = std::move(SBOrErr.get());
7472d2b420aSRafael Espindola 
7482f76cd75SDan Gohman     const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(),
7495159f616SChris Lattner                                                    SB->getBufferSize(), 0);
750b671e34cSAlp Toker     SourceMgr.setMainFileID(
751b671e34cSAlp Toker         SourceMgr.createFileID(File, SourceLocation(), Kind));
75249cc3181SDavid Blaikie     SourceMgr.overrideFileContents(File, std::move(SB));
753409e890fSDaniel Dunbar   }
754409e890fSDaniel Dunbar 
75552765215SDan Gohman   assert(!SourceMgr.getMainFileID().isInvalid() &&
75652765215SDan Gohman          "Couldn't establish MainFileID!");
757409e890fSDaniel Dunbar   return true;
758409e890fSDaniel Dunbar }
7594f2bc55dSDaniel Dunbar 
7604f2bc55dSDaniel Dunbar // High-Level Operations
7614f2bc55dSDaniel Dunbar 
7624f2bc55dSDaniel Dunbar bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
7634f2bc55dSDaniel Dunbar   assert(hasDiagnostics() && "Diagnostics engine is not initialized!");
7644f2bc55dSDaniel Dunbar   assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!");
7654f2bc55dSDaniel Dunbar   assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!");
7664f2bc55dSDaniel Dunbar 
7674f2bc55dSDaniel Dunbar   // FIXME: Take this as an argument, once all the APIs we used have moved to
7684f2bc55dSDaniel Dunbar   // taking it as an input instead of hard-coding llvm::errs.
7690e62c1ccSChris Lattner   raw_ostream &OS = llvm::errs();
7704f2bc55dSDaniel Dunbar 
7714f2bc55dSDaniel Dunbar   // Create the target instance.
77280758084SAlp Toker   setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(),
77380758084SAlp Toker                                          getInvocation().TargetOpts));
7744f2bc55dSDaniel Dunbar   if (!hasTarget())
7754f2bc55dSDaniel Dunbar     return false;
7764f2bc55dSDaniel Dunbar 
7774f2bc55dSDaniel Dunbar   // Inform the target of the language options.
7784f2bc55dSDaniel Dunbar   //
7794f2bc55dSDaniel Dunbar   // FIXME: We shouldn't need to do this, the target should be immutable once
7804f2bc55dSDaniel Dunbar   // created. This complexity should be lifted elsewhere.
78174437975SAlp Toker   getTarget().adjust(getLangOpts());
7824f2bc55dSDaniel Dunbar 
78329898f45SFariborz Jahanian   // rewriter project will change target built-in bool type from its default.
78429898f45SFariborz Jahanian   if (getFrontendOpts().ProgramAction == frontend::RewriteObjC)
78529898f45SFariborz Jahanian     getTarget().noSignedCharForObjCBool();
78629898f45SFariborz Jahanian 
7874f2bc55dSDaniel Dunbar   // Validate/process some options.
7884f2bc55dSDaniel Dunbar   if (getHeaderSearchOpts().Verbose)
7894f2bc55dSDaniel Dunbar     OS << "clang -cc1 version " CLANG_VERSION_STRING
790f988d006SAlp Toker        << " based upon " << BACKEND_PACKAGE_STRING
7918188c8a1SSebastian Pop        << " default target " << llvm::sys::getDefaultTargetTriple() << "\n";
7924f2bc55dSDaniel Dunbar 
7934f2bc55dSDaniel Dunbar   if (getFrontendOpts().ShowTimers)
7944f2bc55dSDaniel Dunbar     createFrontendTimer();
7954f2bc55dSDaniel Dunbar 
796171b780cSDouglas Gregor   if (getFrontendOpts().ShowStats)
797171b780cSDouglas Gregor     llvm::EnableStatistics();
798171b780cSDouglas Gregor 
7994f2bc55dSDaniel Dunbar   for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) {
800eeccb30bSTed Kremenek     // Reset the ID tables if we are reusing the SourceManager and parsing
801eeccb30bSTed Kremenek     // regular files.
802eeccb30bSTed Kremenek     if (hasSourceManager() && !Act.isModelParsingAction())
8034f2bc55dSDaniel Dunbar       getSourceManager().clearIDTables();
8044f2bc55dSDaniel Dunbar 
80532fbe312SDouglas Gregor     if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) {
8064f2bc55dSDaniel Dunbar       Act.Execute();
8074f2bc55dSDaniel Dunbar       Act.EndSourceFile();
8084f2bc55dSDaniel Dunbar     }
8094f2bc55dSDaniel Dunbar   }
8104f2bc55dSDaniel Dunbar 
8117910d7b7SArgyrios Kyrtzidis   // Notify the diagnostic client that all files were processed.
8127910d7b7SArgyrios Kyrtzidis   getDiagnostics().getClient()->finish();
8137910d7b7SArgyrios Kyrtzidis 
814198cb4dfSChris Lattner   if (getDiagnosticOpts().ShowCarets) {
815c79346a5SArgyrios Kyrtzidis     // We can have multiple diagnostics sharing one diagnostic client.
816c79346a5SArgyrios Kyrtzidis     // Get the total number of warnings/errors from the client.
817c79346a5SArgyrios Kyrtzidis     unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings();
818c79346a5SArgyrios Kyrtzidis     unsigned NumErrors = getDiagnostics().getClient()->getNumErrors();
819198cb4dfSChris Lattner 
820198cb4dfSChris Lattner     if (NumWarnings)
821198cb4dfSChris Lattner       OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s");
822198cb4dfSChris Lattner     if (NumWarnings && NumErrors)
823198cb4dfSChris Lattner       OS << " and ";
824198cb4dfSChris Lattner     if (NumErrors)
825198cb4dfSChris Lattner       OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s");
826198cb4dfSChris Lattner     if (NumWarnings || NumErrors)
827198cb4dfSChris Lattner       OS << " generated.\n";
828198cb4dfSChris Lattner   }
8294f2bc55dSDaniel Dunbar 
830aed46fcbSDaniel Dunbar   if (getFrontendOpts().ShowStats && hasFileManager()) {
8314f2bc55dSDaniel Dunbar     getFileManager().PrintStats();
8324f2bc55dSDaniel Dunbar     OS << "\n";
8334f2bc55dSDaniel Dunbar   }
8344f2bc55dSDaniel Dunbar 
835bc467933SArgyrios Kyrtzidis   return !getDiagnostics().getClient()->getNumErrors();
8364f2bc55dSDaniel Dunbar }
8374f2bc55dSDaniel Dunbar 
838faeb1d46SDouglas Gregor /// \brief Determine the appropriate source input kind based on language
839faeb1d46SDouglas Gregor /// options.
840faeb1d46SDouglas Gregor static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) {
841faeb1d46SDouglas Gregor   if (LangOpts.OpenCL)
842faeb1d46SDouglas Gregor     return IK_OpenCL;
843faeb1d46SDouglas Gregor   if (LangOpts.CUDA)
844faeb1d46SDouglas Gregor     return IK_CUDA;
845faeb1d46SDouglas Gregor   if (LangOpts.ObjC1)
846faeb1d46SDouglas Gregor     return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC;
847faeb1d46SDouglas Gregor   return LangOpts.CPlusPlus? IK_CXX : IK_C;
848faeb1d46SDouglas Gregor }
849faeb1d46SDouglas Gregor 
850514b636aSDouglas Gregor /// \brief Compile a module file for the given module, using the options
851b797d59fSBen Langmuir /// provided by the importing compiler instance. Returns true if the module
852b797d59fSBen Langmuir /// was built without errors.
853b797d59fSBen Langmuir static bool compileModuleImpl(CompilerInstance &ImportingInstance,
854af8f0263SDouglas Gregor                               SourceLocation ImportLoc,
855de3ef502SDouglas Gregor                               Module *Module,
8566dc57927SDouglas Gregor                               StringRef ModuleFileName) {
857514b636aSDouglas Gregor   ModuleMap &ModMap
858514b636aSDouglas Gregor     = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
859514b636aSDouglas Gregor 
860faeb1d46SDouglas Gregor   // Construct a compiler invocation for creating this module.
861c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<CompilerInvocation> Invocation
862faeb1d46SDouglas Gregor     (new CompilerInvocation(ImportingInstance.getInvocation()));
86344bf68d8SDouglas Gregor 
864f545f67dSDouglas Gregor   PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
865f545f67dSDouglas Gregor 
86644bf68d8SDouglas Gregor   // For any options that aren't intended to affect how a module is built,
86744bf68d8SDouglas Gregor   // reset them to their default values.
8688cf47df7STed Kremenek   Invocation->getLangOpts()->resetNonModularOptions();
869f545f67dSDouglas Gregor   PPOpts.resetNonModularOptions();
87044bf68d8SDouglas Gregor 
8715dc3899cSDouglas Gregor   // Remove any macro definitions that are explicitly ignored by the module.
8725dc3899cSDouglas Gregor   // They aren't supposed to affect how the module is built anyway.
8735dc3899cSDouglas Gregor   const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
874bbdd7640SBenjamin Kramer   PPOpts.Macros.erase(
875bbdd7640SBenjamin Kramer       std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(),
876bbdd7640SBenjamin Kramer                      [&HSOpts](const std::pair<std::string, bool> &def) {
877bbdd7640SBenjamin Kramer         StringRef MacroDef = def.first;
878bbdd7640SBenjamin Kramer         return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0;
879bbdd7640SBenjamin Kramer       }),
8805dc3899cSDouglas Gregor       PPOpts.Macros.end());
8815dc3899cSDouglas Gregor 
8827d106e42SDouglas Gregor   // Note the name of the module we're building.
8836dc57927SDouglas Gregor   Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName();
8847d106e42SDouglas Gregor 
8857a626570SDouglas Gregor   // Make sure that the failed-module structure has been allocated in
8867a626570SDouglas Gregor   // the importing instance, and propagate the pointer to the newly-created
8877a626570SDouglas Gregor   // instance.
8887a626570SDouglas Gregor   PreprocessorOptions &ImportingPPOpts
8897a626570SDouglas Gregor     = ImportingInstance.getInvocation().getPreprocessorOpts();
8907a626570SDouglas Gregor   if (!ImportingPPOpts.FailedModules)
8917a626570SDouglas Gregor     ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet;
8927a626570SDouglas Gregor   PPOpts.FailedModules = ImportingPPOpts.FailedModules;
8937a626570SDouglas Gregor 
894514b636aSDouglas Gregor   // If there is a module map file, build the module using the module map.
895514b636aSDouglas Gregor   // Set up the inputs/outputs so that we build the module from its umbrella
896514b636aSDouglas Gregor   // header.
897514b636aSDouglas Gregor   FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
898514b636aSDouglas Gregor   FrontendOpts.OutputFile = ModuleFileName.str();
899514b636aSDouglas Gregor   FrontendOpts.DisableFree = false;
900c1bbec85SDouglas Gregor   FrontendOpts.GenerateGlobalModuleIndex = false;
901514b636aSDouglas Gregor   FrontendOpts.Inputs.clear();
902f545f67dSDouglas Gregor   InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts());
903f545f67dSDouglas Gregor 
904f545f67dSDouglas Gregor   // Don't free the remapped file buffers; they are owned by our caller.
905f545f67dSDouglas Gregor   PPOpts.RetainRemappedFileBuffers = true;
906514b636aSDouglas Gregor 
907514b636aSDouglas Gregor   Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
908514b636aSDouglas Gregor   assert(ImportingInstance.getInvocation().getModuleHash() ==
909514b636aSDouglas Gregor          Invocation->getModuleHash() && "Module hash mismatch!");
910514b636aSDouglas Gregor 
911514b636aSDouglas Gregor   // Construct a compiler instance that will be used to actually create the
912514b636aSDouglas Gregor   // module.
9132255f2ceSJohn Thompson   CompilerInstance Instance(/*BuildingModule=*/true);
914514b636aSDouglas Gregor   Instance.setInvocation(&*Invocation);
9156b930967SDouglas Gregor 
9166b930967SDouglas Gregor   Instance.createDiagnostics(new ForwardingDiagnosticConsumer(
9176b930967SDouglas Gregor                                    ImportingInstance.getDiagnosticClient()),
91830071ceaSDouglas Gregor                              /*ShouldOwnClient=*/true);
919514b636aSDouglas Gregor 
920c8130a74SBen Langmuir   Instance.setVirtualFileSystem(&ImportingInstance.getVirtualFileSystem());
921c8130a74SBen Langmuir 
92263365431SDouglas Gregor   // Note that this module is part of the module build stack, so that we
923af8f0263SDouglas Gregor   // can detect cycles in the module graph.
924d066d4c8SBen Langmuir   Instance.setFileManager(&ImportingInstance.getFileManager());
925af8f0263SDouglas Gregor   Instance.createSourceManager(Instance.getFileManager());
926af8f0263SDouglas Gregor   SourceManager &SourceMgr = Instance.getSourceManager();
92763365431SDouglas Gregor   SourceMgr.setModuleBuildStack(
92863365431SDouglas Gregor     ImportingInstance.getSourceManager().getModuleBuildStack());
92963365431SDouglas Gregor   SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(),
930af8f0263SDouglas Gregor     FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));
931af8f0263SDouglas Gregor 
93286d1259cSJustin Bogner   // If we're collecting module dependencies, we need to share a collector
93386d1259cSJustin Bogner   // between all of the module CompilerInstances.
93486d1259cSJustin Bogner   Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector());
93586d1259cSJustin Bogner 
9361f76c4e8SManuel Klimek   // Get or create the module map that we'll use to build this module.
9371f76c4e8SManuel Klimek   std::string InferredModuleMapContent;
9381f76c4e8SManuel Klimek   if (const FileEntry *ModuleMapFile =
9391f76c4e8SManuel Klimek           ModMap.getContainingModuleMapFile(Module)) {
9401f76c4e8SManuel Klimek     // Use the module map where this module resides.
9411f76c4e8SManuel Klimek     FrontendOpts.Inputs.push_back(
9421f76c4e8SManuel Klimek         FrontendInputFile(ModuleMapFile->getName(), IK));
9431f76c4e8SManuel Klimek   } else {
9441f76c4e8SManuel Klimek     llvm::raw_string_ostream OS(InferredModuleMapContent);
9451f76c4e8SManuel Klimek     Module->print(OS);
9461f76c4e8SManuel Klimek     OS.flush();
9471f76c4e8SManuel Klimek     FrontendOpts.Inputs.push_back(
9481f76c4e8SManuel Klimek         FrontendInputFile("__inferred_module.map", IK));
9491f76c4e8SManuel Klimek 
950d87f8d76SRafael Espindola     std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
9511f76c4e8SManuel Klimek         llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
9521f76c4e8SManuel Klimek     ModuleMapFile = Instance.getFileManager().getVirtualFile(
9531f76c4e8SManuel Klimek         "__inferred_module.map", InferredModuleMapContent.size(), 0);
95449cc3181SDavid Blaikie     SourceMgr.overrideFileContents(ModuleMapFile, std::move(ModuleMapBuffer));
9551f76c4e8SManuel Klimek   }
956af8f0263SDouglas Gregor 
9579d6448b1SBen Langmuir   // Construct a module-generating action. Passing through the module map is
958beee15e7SBen Langmuir   // safe because the FileManager is shared between the compiler instances.
9599d6448b1SBen Langmuir   GenerateModuleAction CreateModuleAction(
9609d6448b1SBen Langmuir       ModMap.getModuleMapFileForUniquing(Module), Module->IsSystem);
961514b636aSDouglas Gregor 
96299891da7SRichard Smith   ImportingInstance.getDiagnostics().Report(ImportLoc,
96399891da7SRichard Smith                                             diag::remark_module_build)
96499891da7SRichard Smith     << Module->Name << ModuleFileName;
96599891da7SRichard Smith 
966514b636aSDouglas Gregor   // Execute the action to actually build the module in-place. Use a separate
967514b636aSDouglas Gregor   // thread so that we get a stack large enough.
968514b636aSDouglas Gregor   const unsigned ThreadStackSize = 8 << 20;
969514b636aSDouglas Gregor   llvm::CrashRecoveryContext CRC;
970841f1c78SRichard Smith   CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(CreateModuleAction); },
971841f1c78SRichard Smith                         ThreadStackSize);
9726b930967SDouglas Gregor 
97399891da7SRichard Smith   ImportingInstance.getDiagnostics().Report(ImportLoc,
97499891da7SRichard Smith                                             diag::remark_module_build_done)
97599891da7SRichard Smith     << Module->Name;
97699891da7SRichard Smith 
977f545f67dSDouglas Gregor   // Delete the temporary module map file.
978f545f67dSDouglas Gregor   // FIXME: Even though we're executing under crash protection, it would still
979f545f67dSDouglas Gregor   // be nice to do this with RemoveFileOnSignal when we can. However, that
980f545f67dSDouglas Gregor   // doesn't make sense for all clients, so clean this up manually.
98113afbf42SBenjamin Kramer   Instance.clearOutputFiles(/*EraseFiles=*/true);
9825e306b12SDouglas Gregor 
9835e306b12SDouglas Gregor   // We've rebuilt a module. If we're allowed to generate or update the global
9845e306b12SDouglas Gregor   // module index, record that fact in the importing compiler instance.
985c1bbec85SDouglas Gregor   if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) {
9865e306b12SDouglas Gregor     ImportingInstance.setBuildGlobalModuleIndex(true);
9875e306b12SDouglas Gregor   }
988b797d59fSBen Langmuir 
989b797d59fSBen Langmuir   return !Instance.getDiagnostics().hasErrorOccurred();
990faeb1d46SDouglas Gregor }
991faeb1d46SDouglas Gregor 
992dbdc0368SBen Langmuir static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
9934382fe74SArgyrios Kyrtzidis                                  SourceLocation ImportLoc,
994b797d59fSBen Langmuir                                  SourceLocation ModuleNameLoc, Module *Module,
9954382fe74SArgyrios Kyrtzidis                                  StringRef ModuleFileName) {
996d213aab7SBen Langmuir   DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics();
997d213aab7SBen Langmuir 
998b797d59fSBen Langmuir   auto diagnoseBuildFailure = [&] {
999d213aab7SBen Langmuir     Diags.Report(ModuleNameLoc, diag::err_module_not_built)
1000b797d59fSBen Langmuir         << Module->Name << SourceRange(ImportLoc, ModuleNameLoc);
1001b797d59fSBen Langmuir   };
1002b797d59fSBen Langmuir 
10034382fe74SArgyrios Kyrtzidis   // FIXME: have LockFileManager return an error_code so that we can
10044382fe74SArgyrios Kyrtzidis   // avoid the mkdir when the directory already exists.
10054382fe74SArgyrios Kyrtzidis   StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
10064382fe74SArgyrios Kyrtzidis   llvm::sys::fs::create_directories(Dir);
10074382fe74SArgyrios Kyrtzidis 
10084382fe74SArgyrios Kyrtzidis   while (1) {
1009dbdc0368SBen Langmuir     unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing;
10104382fe74SArgyrios Kyrtzidis     llvm::LockFileManager Locked(ModuleFileName);
10114382fe74SArgyrios Kyrtzidis     switch (Locked) {
10124382fe74SArgyrios Kyrtzidis     case llvm::LockFileManager::LFS_Error:
1013d213aab7SBen Langmuir       Diags.Report(ModuleNameLoc, diag::err_module_lock_failure)
1014d213aab7SBen Langmuir           << Module->Name;
1015dbdc0368SBen Langmuir       return false;
10164382fe74SArgyrios Kyrtzidis 
10174382fe74SArgyrios Kyrtzidis     case llvm::LockFileManager::LFS_Owned:
1018dbdc0368SBen Langmuir       // We're responsible for building the module ourselves.
1019b797d59fSBen Langmuir       if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module,
1020b797d59fSBen Langmuir                              ModuleFileName)) {
1021b797d59fSBen Langmuir         diagnoseBuildFailure();
1022b797d59fSBen Langmuir         return false;
1023b797d59fSBen Langmuir       }
10244382fe74SArgyrios Kyrtzidis       break;
10254382fe74SArgyrios Kyrtzidis 
10264382fe74SArgyrios Kyrtzidis     case llvm::LockFileManager::LFS_Shared:
10274382fe74SArgyrios Kyrtzidis       // Someone else is responsible for building the module. Wait for them to
10284382fe74SArgyrios Kyrtzidis       // finish.
10291daf4801SBen Langmuir       switch (Locked.waitForUnlock()) {
10301daf4801SBen Langmuir       case llvm::LockFileManager::Res_Success:
1031dbdc0368SBen Langmuir         ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate;
1032dbdc0368SBen Langmuir         break;
10331daf4801SBen Langmuir       case llvm::LockFileManager::Res_OwnerDied:
10341daf4801SBen Langmuir         continue; // try again to get the lock.
10351daf4801SBen Langmuir       case llvm::LockFileManager::Res_Timeout:
10361daf4801SBen Langmuir         Diags.Report(ModuleNameLoc, diag::err_module_lock_timeout)
10371daf4801SBen Langmuir             << Module->Name;
10381daf4801SBen Langmuir         // Clear the lock file so that future invokations can make progress.
10391daf4801SBen Langmuir         Locked.unsafeRemoveLockFile();
10401daf4801SBen Langmuir         return false;
10411daf4801SBen Langmuir       }
10421daf4801SBen Langmuir       break;
10434382fe74SArgyrios Kyrtzidis     }
10444382fe74SArgyrios Kyrtzidis 
1045dbdc0368SBen Langmuir     // Try to read the module file, now that we've compiled it.
1046dbdc0368SBen Langmuir     ASTReader::ASTReadResult ReadResult =
1047dbdc0368SBen Langmuir         ImportingInstance.getModuleManager()->ReadAST(
1048e842a474SRichard Smith             ModuleFileName, serialization::MK_ImplicitModule, ImportLoc,
1049dbdc0368SBen Langmuir             ModuleLoadCapabilities);
1050dbdc0368SBen Langmuir 
1051dbdc0368SBen Langmuir     if (ReadResult == ASTReader::OutOfDate &&
1052dbdc0368SBen Langmuir         Locked == llvm::LockFileManager::LFS_Shared) {
1053dbdc0368SBen Langmuir       // The module may be out of date in the presence of file system races,
1054dbdc0368SBen Langmuir       // or if one of its imports depends on header search paths that are not
1055dbdc0368SBen Langmuir       // consistent with this ImportingInstance.  Try again...
1056dbdc0368SBen Langmuir       continue;
1057dbdc0368SBen Langmuir     } else if (ReadResult == ASTReader::Missing) {
1058b797d59fSBen Langmuir       diagnoseBuildFailure();
1059d213aab7SBen Langmuir     } else if (ReadResult != ASTReader::Success &&
1060d213aab7SBen Langmuir                !Diags.hasErrorOccurred()) {
1061d213aab7SBen Langmuir       // The ASTReader didn't diagnose the error, so conservatively report it.
1062d213aab7SBen Langmuir       diagnoseBuildFailure();
1063dbdc0368SBen Langmuir     }
1064dbdc0368SBen Langmuir     return ReadResult == ASTReader::Success;
10654382fe74SArgyrios Kyrtzidis   }
10664382fe74SArgyrios Kyrtzidis }
10674382fe74SArgyrios Kyrtzidis 
106835b13eceSDouglas Gregor /// \brief Diagnose differences between the current definition of the given
106935b13eceSDouglas Gregor /// configuration macro and the definition provided on the command line.
107035b13eceSDouglas Gregor static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,
107135b13eceSDouglas Gregor                              Module *Mod, SourceLocation ImportLoc) {
107235b13eceSDouglas Gregor   IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro);
107335b13eceSDouglas Gregor   SourceManager &SourceMgr = PP.getSourceManager();
107435b13eceSDouglas Gregor 
107535b13eceSDouglas Gregor   // If this identifier has never had a macro definition, then it could
107635b13eceSDouglas Gregor   // not have changed.
107735b13eceSDouglas Gregor   if (!Id->hadMacroDefinition())
107835b13eceSDouglas Gregor     return;
107935b13eceSDouglas Gregor 
108035b13eceSDouglas Gregor   // If this identifier does not currently have a macro definition,
108135b13eceSDouglas Gregor   // check whether it had one on the command line.
108235b13eceSDouglas Gregor   if (!Id->hasMacroDefinition()) {
1083b6210dffSArgyrios Kyrtzidis     MacroDirective::DefInfo LatestDef =
1084b6210dffSArgyrios Kyrtzidis         PP.getMacroDirectiveHistory(Id)->getDefinition();
1085b6210dffSArgyrios Kyrtzidis     for (MacroDirective::DefInfo Def = LatestDef; Def;
1086b6210dffSArgyrios Kyrtzidis            Def = Def.getPreviousDefinition()) {
1087b6210dffSArgyrios Kyrtzidis       FileID FID = SourceMgr.getFileID(Def.getLocation());
108835b13eceSDouglas Gregor       if (FID.isInvalid())
108935b13eceSDouglas Gregor         continue;
109035b13eceSDouglas Gregor 
109135b13eceSDouglas Gregor       // We only care about the predefines buffer.
109205ba2a05SDouglas Gregor       if (FID != PP.getPredefinesFileID())
109335b13eceSDouglas Gregor         continue;
109435b13eceSDouglas Gregor 
109535b13eceSDouglas Gregor       // This macro was defined on the command line, then #undef'd later.
109635b13eceSDouglas Gregor       // Complain.
109735b13eceSDouglas Gregor       PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
109835b13eceSDouglas Gregor         << true << ConfigMacro << Mod->getFullModuleName();
1099b6210dffSArgyrios Kyrtzidis       if (LatestDef.isUndefined())
1100b6210dffSArgyrios Kyrtzidis         PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
110135b13eceSDouglas Gregor           << true;
110235b13eceSDouglas Gregor       return;
110335b13eceSDouglas Gregor     }
110435b13eceSDouglas Gregor 
110535b13eceSDouglas Gregor     // Okay: no definition in the predefines buffer.
110635b13eceSDouglas Gregor     return;
110735b13eceSDouglas Gregor   }
110835b13eceSDouglas Gregor 
110935b13eceSDouglas Gregor   // This identifier has a macro definition. Check whether we had a definition
111035b13eceSDouglas Gregor   // on the command line.
1111b6210dffSArgyrios Kyrtzidis   MacroDirective::DefInfo LatestDef =
1112b6210dffSArgyrios Kyrtzidis       PP.getMacroDirectiveHistory(Id)->getDefinition();
1113b6210dffSArgyrios Kyrtzidis   MacroDirective::DefInfo PredefinedDef;
1114b6210dffSArgyrios Kyrtzidis   for (MacroDirective::DefInfo Def = LatestDef; Def;
1115b6210dffSArgyrios Kyrtzidis          Def = Def.getPreviousDefinition()) {
1116b6210dffSArgyrios Kyrtzidis     FileID FID = SourceMgr.getFileID(Def.getLocation());
111735b13eceSDouglas Gregor     if (FID.isInvalid())
111835b13eceSDouglas Gregor       continue;
111935b13eceSDouglas Gregor 
112035b13eceSDouglas Gregor     // We only care about the predefines buffer.
112105ba2a05SDouglas Gregor     if (FID != PP.getPredefinesFileID())
112235b13eceSDouglas Gregor       continue;
112335b13eceSDouglas Gregor 
1124b6210dffSArgyrios Kyrtzidis     PredefinedDef = Def;
112535b13eceSDouglas Gregor     break;
112635b13eceSDouglas Gregor   }
112735b13eceSDouglas Gregor 
112835b13eceSDouglas Gregor   // If there was no definition for this macro in the predefines buffer,
112935b13eceSDouglas Gregor   // complain.
1130b6210dffSArgyrios Kyrtzidis   if (!PredefinedDef ||
1131b6210dffSArgyrios Kyrtzidis       (!PredefinedDef.getLocation().isValid() &&
1132b6210dffSArgyrios Kyrtzidis        PredefinedDef.getUndefLocation().isValid())) {
113335b13eceSDouglas Gregor     PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
113435b13eceSDouglas Gregor       << false << ConfigMacro << Mod->getFullModuleName();
1135b6210dffSArgyrios Kyrtzidis     PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
113635b13eceSDouglas Gregor       << false;
113735b13eceSDouglas Gregor     return;
113835b13eceSDouglas Gregor   }
113935b13eceSDouglas Gregor 
114035b13eceSDouglas Gregor   // If the current macro definition is the same as the predefined macro
114135b13eceSDouglas Gregor   // definition, it's okay.
1142b6210dffSArgyrios Kyrtzidis   if (LatestDef.getMacroInfo() == PredefinedDef.getMacroInfo() ||
11430c2f30b9SArgyrios Kyrtzidis       LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP,
11440c2f30b9SArgyrios Kyrtzidis                                               /*Syntactically=*/true))
114535b13eceSDouglas Gregor     return;
114635b13eceSDouglas Gregor 
114735b13eceSDouglas Gregor   // The macro definitions differ.
114835b13eceSDouglas Gregor   PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
114935b13eceSDouglas Gregor     << false << ConfigMacro << Mod->getFullModuleName();
1150b6210dffSArgyrios Kyrtzidis   PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
115135b13eceSDouglas Gregor     << false;
115235b13eceSDouglas Gregor }
115335b13eceSDouglas Gregor 
1154527b1c95SDouglas Gregor /// \brief Write a new timestamp file with the given path.
1155527b1c95SDouglas Gregor static void writeTimestampFile(StringRef TimestampFile) {
1156dae941a6SRafael Espindola   std::error_code EC;
1157dae941a6SRafael Espindola   llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None);
1158527b1c95SDouglas Gregor }
1159527b1c95SDouglas Gregor 
1160527b1c95SDouglas Gregor /// \brief Prune the module cache of modules that haven't been accessed in
1161527b1c95SDouglas Gregor /// a long time.
1162527b1c95SDouglas Gregor static void pruneModuleCache(const HeaderSearchOptions &HSOpts) {
1163527b1c95SDouglas Gregor   struct stat StatBuf;
1164527b1c95SDouglas Gregor   llvm::SmallString<128> TimestampFile;
1165527b1c95SDouglas Gregor   TimestampFile = HSOpts.ModuleCachePath;
1166527b1c95SDouglas Gregor   llvm::sys::path::append(TimestampFile, "modules.timestamp");
1167527b1c95SDouglas Gregor 
1168527b1c95SDouglas Gregor   // Try to stat() the timestamp file.
1169527b1c95SDouglas Gregor   if (::stat(TimestampFile.c_str(), &StatBuf)) {
1170527b1c95SDouglas Gregor     // If the timestamp file wasn't there, create one now.
1171527b1c95SDouglas Gregor     if (errno == ENOENT) {
1172527b1c95SDouglas Gregor       writeTimestampFile(TimestampFile);
1173527b1c95SDouglas Gregor     }
1174527b1c95SDouglas Gregor     return;
1175527b1c95SDouglas Gregor   }
1176527b1c95SDouglas Gregor 
1177527b1c95SDouglas Gregor   // Check whether the time stamp is older than our pruning interval.
1178527b1c95SDouglas Gregor   // If not, do nothing.
1179527b1c95SDouglas Gregor   time_t TimeStampModTime = StatBuf.st_mtime;
118049a2790fSCraig Topper   time_t CurrentTime = time(nullptr);
1181dbcf5037SBenjamin Kramer   if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval))
1182527b1c95SDouglas Gregor     return;
1183527b1c95SDouglas Gregor 
1184527b1c95SDouglas Gregor   // Write a new timestamp file so that nobody else attempts to prune.
1185527b1c95SDouglas Gregor   // There is a benign race condition here, if two Clang instances happen to
1186527b1c95SDouglas Gregor   // notice at the same time that the timestamp is out-of-date.
1187527b1c95SDouglas Gregor   writeTimestampFile(TimestampFile);
1188527b1c95SDouglas Gregor 
1189527b1c95SDouglas Gregor   // Walk the entire module cache, looking for unused module files and module
1190527b1c95SDouglas Gregor   // indices.
1191c080917eSRafael Espindola   std::error_code EC;
1192527b1c95SDouglas Gregor   SmallString<128> ModuleCachePathNative;
1193527b1c95SDouglas Gregor   llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative);
1194527b1c95SDouglas Gregor   for (llvm::sys::fs::directory_iterator
1195527b1c95SDouglas Gregor          Dir(ModuleCachePathNative.str(), EC), DirEnd;
1196527b1c95SDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
1197527b1c95SDouglas Gregor     // If we don't have a directory, there's nothing to look into.
1198a07f720aSRafael Espindola     if (!llvm::sys::fs::is_directory(Dir->path()))
1199527b1c95SDouglas Gregor       continue;
1200527b1c95SDouglas Gregor 
1201527b1c95SDouglas Gregor     // Walk all of the files within this directory.
1202527b1c95SDouglas Gregor     for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd;
1203527b1c95SDouglas Gregor          File != FileEnd && !EC; File.increment(EC)) {
1204527b1c95SDouglas Gregor       // We only care about module and global module index files.
1205f430da4dSDmitri Gribenko       StringRef Extension = llvm::sys::path::extension(File->path());
1206f430da4dSDmitri Gribenko       if (Extension != ".pcm" && Extension != ".timestamp" &&
1207f430da4dSDmitri Gribenko           llvm::sys::path::filename(File->path()) != "modules.idx")
1208527b1c95SDouglas Gregor         continue;
1209527b1c95SDouglas Gregor 
1210527b1c95SDouglas Gregor       // Look at this file. If we can't stat it, there's nothing interesting
1211527b1c95SDouglas Gregor       // there.
1212f430da4dSDmitri Gribenko       if (::stat(File->path().c_str(), &StatBuf))
1213527b1c95SDouglas Gregor         continue;
1214527b1c95SDouglas Gregor 
1215527b1c95SDouglas Gregor       // If the file has been used recently enough, leave it there.
1216527b1c95SDouglas Gregor       time_t FileAccessTime = StatBuf.st_atime;
1217dbcf5037SBenjamin Kramer       if (CurrentTime - FileAccessTime <=
1218dbcf5037SBenjamin Kramer               time_t(HSOpts.ModuleCachePruneAfter)) {
1219527b1c95SDouglas Gregor         continue;
1220527b1c95SDouglas Gregor       }
1221527b1c95SDouglas Gregor 
1222527b1c95SDouglas Gregor       // Remove the file.
1223f430da4dSDmitri Gribenko       llvm::sys::fs::remove(File->path());
1224f430da4dSDmitri Gribenko 
1225f430da4dSDmitri Gribenko       // Remove the timestamp file.
1226f430da4dSDmitri Gribenko       std::string TimpestampFilename = File->path() + ".timestamp";
1227f430da4dSDmitri Gribenko       llvm::sys::fs::remove(TimpestampFilename);
1228527b1c95SDouglas Gregor     }
1229527b1c95SDouglas Gregor 
1230527b1c95SDouglas Gregor     // If we removed all of the files in the directory, remove the directory
1231527b1c95SDouglas Gregor     // itself.
1232f430da4dSDmitri Gribenko     if (llvm::sys::fs::directory_iterator(Dir->path(), EC) ==
1233f430da4dSDmitri Gribenko             llvm::sys::fs::directory_iterator() && !EC)
12342a008784SRafael Espindola       llvm::sys::fs::remove(Dir->path());
1235527b1c95SDouglas Gregor   }
1236527b1c95SDouglas Gregor }
1237527b1c95SDouglas Gregor 
12382255f2ceSJohn Thompson void CompilerInstance::createModuleManager() {
12392255f2ceSJohn Thompson   if (!ModuleManager) {
12402255f2ceSJohn Thompson     if (!hasASTContext())
12412255f2ceSJohn Thompson       createASTContext();
12422255f2ceSJohn Thompson 
12432255f2ceSJohn Thompson     // If we're not recursively building a module, check whether we
12442255f2ceSJohn Thompson     // need to prune the module cache.
12452255f2ceSJohn Thompson     if (getSourceManager().getModuleBuildStack().empty() &&
12462255f2ceSJohn Thompson         getHeaderSearchOpts().ModuleCachePruneInterval > 0 &&
12472255f2ceSJohn Thompson         getHeaderSearchOpts().ModuleCachePruneAfter > 0) {
12482255f2ceSJohn Thompson       pruneModuleCache(getHeaderSearchOpts());
12492255f2ceSJohn Thompson     }
12502255f2ceSJohn Thompson 
12512255f2ceSJohn Thompson     HeaderSearchOptions &HSOpts = getHeaderSearchOpts();
12522255f2ceSJohn Thompson     std::string Sysroot = HSOpts.Sysroot;
12532255f2ceSJohn Thompson     const PreprocessorOptions &PPOpts = getPreprocessorOpts();
12542255f2ceSJohn Thompson     ModuleManager = new ASTReader(getPreprocessor(), *Context,
12552255f2ceSJohn Thompson                                   Sysroot.empty() ? "" : Sysroot.c_str(),
12562255f2ceSJohn Thompson                                   PPOpts.DisablePCHValidation,
12572255f2ceSJohn Thompson                                   /*AllowASTWithCompilerErrors=*/false,
12582255f2ceSJohn Thompson                                   /*AllowConfigurationMismatch=*/false,
12592255f2ceSJohn Thompson                                   HSOpts.ModulesValidateSystemHeaders,
12602255f2ceSJohn Thompson                                   getFrontendOpts().UseGlobalModuleIndex);
12612255f2ceSJohn Thompson     if (hasASTConsumer()) {
12622255f2ceSJohn Thompson       ModuleManager->setDeserializationListener(
12632255f2ceSJohn Thompson         getASTConsumer().GetASTDeserializationListener());
12642255f2ceSJohn Thompson       getASTContext().setASTMutationListener(
12652255f2ceSJohn Thompson         getASTConsumer().GetASTMutationListener());
12662255f2ceSJohn Thompson     }
12672255f2ceSJohn Thompson     getASTContext().setExternalSource(ModuleManager);
12682255f2ceSJohn Thompson     if (hasSema())
12692255f2ceSJohn Thompson       ModuleManager->InitializeSema(getSema());
12702255f2ceSJohn Thompson     if (hasASTConsumer())
12712255f2ceSJohn Thompson       ModuleManager->StartTranslationUnit(&getASTConsumer());
12722255f2ceSJohn Thompson   }
12732255f2ceSJohn Thompson }
12742255f2ceSJohn Thompson 
1275d4b230b3SRichard Smith bool CompilerInstance::loadModuleFile(StringRef FileName) {
1276d4b230b3SRichard Smith   // Helper to recursively read the module names for all modules we're adding.
1277d4b230b3SRichard Smith   // We mark these as known and redirect any attempt to load that module to
1278d4b230b3SRichard Smith   // the files we were handed.
1279d4b230b3SRichard Smith   struct ReadModuleNames : ASTReaderListener {
1280d4b230b3SRichard Smith     CompilerInstance &CI;
1281d4b230b3SRichard Smith     std::vector<StringRef> ModuleFileStack;
128237bd29a5SRichard Smith     std::vector<StringRef> ModuleNameStack;
1283d4b230b3SRichard Smith     bool Failed;
1284d4b230b3SRichard Smith     bool TopFileIsModule;
1285e842a474SRichard Smith 
1286d4b230b3SRichard Smith     ReadModuleNames(CompilerInstance &CI)
1287d4b230b3SRichard Smith         : CI(CI), Failed(false), TopFileIsModule(false) {}
1288e842a474SRichard Smith 
1289d4b230b3SRichard Smith     bool needsImportVisitation() const override { return true; }
1290e842a474SRichard Smith 
1291d4b230b3SRichard Smith     void visitImport(StringRef FileName) override {
12928cebe37fSRichard Smith       if (!CI.ExplicitlyLoadedModuleFiles.insert(FileName).second) {
12938cebe37fSRichard Smith         if (ModuleFileStack.size() == 0)
12948cebe37fSRichard Smith           TopFileIsModule = true;
12955638c114SRichard Smith         return;
12968cebe37fSRichard Smith       }
12975638c114SRichard Smith 
1298d4b230b3SRichard Smith       ModuleFileStack.push_back(FileName);
129937bd29a5SRichard Smith       ModuleNameStack.push_back(StringRef());
1300d4b230b3SRichard Smith       if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),
1301d4b230b3SRichard Smith                                              *this)) {
130237bd29a5SRichard Smith         CI.getDiagnostics().Report(
130337bd29a5SRichard Smith             SourceLocation(), CI.getFileManager().getBufferForFile(FileName)
130437bd29a5SRichard Smith                                   ? diag::err_module_file_invalid
130537bd29a5SRichard Smith                                   : diag::err_module_file_not_found)
1306e842a474SRichard Smith             << FileName;
130737bd29a5SRichard Smith         for (int I = ModuleFileStack.size() - 2; I >= 0; --I)
130837bd29a5SRichard Smith           CI.getDiagnostics().Report(SourceLocation(),
130937bd29a5SRichard Smith                                      diag::note_module_file_imported_by)
131037bd29a5SRichard Smith               << ModuleFileStack[I]
131137bd29a5SRichard Smith               << !ModuleNameStack[I].empty() << ModuleNameStack[I];
1312d4b230b3SRichard Smith         Failed = true;
1313e842a474SRichard Smith       }
131437bd29a5SRichard Smith       ModuleNameStack.pop_back();
1315d4b230b3SRichard Smith       ModuleFileStack.pop_back();
1316d4b230b3SRichard Smith     }
1317d4b230b3SRichard Smith 
1318d4b230b3SRichard Smith     void ReadModuleName(StringRef ModuleName) override {
1319d4b230b3SRichard Smith       if (ModuleFileStack.size() == 1)
1320d4b230b3SRichard Smith         TopFileIsModule = true;
132137bd29a5SRichard Smith       ModuleNameStack.back() = ModuleName;
1322d4b230b3SRichard Smith 
1323d4b230b3SRichard Smith       auto &ModuleFile = CI.ModuleFileOverrides[ModuleName];
13240c6387f7SRichard Smith       if (!ModuleFile.empty() &&
13250c6387f7SRichard Smith           CI.getFileManager().getFile(ModuleFile) !=
13260c6387f7SRichard Smith               CI.getFileManager().getFile(ModuleFileStack.back()))
1327d4b230b3SRichard Smith         CI.getDiagnostics().Report(SourceLocation(),
1328d4b230b3SRichard Smith                                    diag::err_conflicting_module_files)
1329d4b230b3SRichard Smith             << ModuleName << ModuleFile << ModuleFileStack.back();
1330d4b230b3SRichard Smith       ModuleFile = ModuleFileStack.back();
1331d4b230b3SRichard Smith     }
1332d4b230b3SRichard Smith   } RMN(*this);
1333d4b230b3SRichard Smith 
1334*7f330cdbSRichard Smith   // If we don't already have an ASTReader, create one now.
1335*7f330cdbSRichard Smith   if (!ModuleManager)
1336*7f330cdbSRichard Smith     createModuleManager();
1337*7f330cdbSRichard Smith 
1338*7f330cdbSRichard Smith   // Tell the module manager about this module file.
1339*7f330cdbSRichard Smith   if (getModuleManager()->getModuleManager().addKnownModuleFile(FileName)) {
1340*7f330cdbSRichard Smith     getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_found)
1341*7f330cdbSRichard Smith       << FileName;
1342*7f330cdbSRichard Smith     return false;
1343*7f330cdbSRichard Smith   }
1344*7f330cdbSRichard Smith 
1345*7f330cdbSRichard Smith   // Build our mapping of module names to module files from this file
1346*7f330cdbSRichard Smith   // and its imports.
1347d4b230b3SRichard Smith   RMN.visitImport(FileName);
1348d4b230b3SRichard Smith 
1349d4b230b3SRichard Smith   if (RMN.Failed)
1350d4b230b3SRichard Smith     return false;
1351d4b230b3SRichard Smith 
1352d4b230b3SRichard Smith   // If we never found a module name for the top file, then it's not a module,
1353d4b230b3SRichard Smith   // it's a PCH or preamble or something.
1354d4b230b3SRichard Smith   if (!RMN.TopFileIsModule) {
1355d4b230b3SRichard Smith     getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_module)
1356d4b230b3SRichard Smith       << FileName;
1357d4b230b3SRichard Smith     return false;
1358d4b230b3SRichard Smith   }
1359d4b230b3SRichard Smith 
1360d4b230b3SRichard Smith   return true;
1361e842a474SRichard Smith }
1362e842a474SRichard Smith 
1363e842a474SRichard Smith ModuleLoadResult
13647a626570SDouglas Gregor CompilerInstance::loadModule(SourceLocation ImportLoc,
1365ff2be53fSDouglas Gregor                              ModuleIdPath Path,
1366bcfc7d02SDouglas Gregor                              Module::NameVisibilityKind Visibility,
1367bcfc7d02SDouglas Gregor                              bool IsInclusionDirective) {
136892304e00SRichard Smith   // Determine what file we're searching from.
136992304e00SRichard Smith   StringRef ModuleName = Path[0].first->getName();
137092304e00SRichard Smith   SourceLocation ModuleNameLoc = Path[0].second;
137192304e00SRichard Smith 
13721805b8a4SDouglas Gregor   // If we've already handled this import, just return the cached result.
13731805b8a4SDouglas Gregor   // This one-element cache is important to eliminate redundant diagnostics
13741805b8a4SDouglas Gregor   // when both the preprocessor and parser see the same import declaration.
1375ff2be53fSDouglas Gregor   if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) {
1376ff2be53fSDouglas Gregor     // Make the named module visible.
1377b537a3a6SBen Langmuir     if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule &&
1378b537a3a6SBen Langmuir         ModuleName != getLangOpts().ImplementationOfModule)
1379125df058SArgyrios Kyrtzidis       ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility,
1380fb912657SDouglas Gregor                                        ImportLoc, /*Complain=*/false);
138169021974SDouglas Gregor     return LastModuleImportResult;
1382ff2be53fSDouglas Gregor   }
13831805b8a4SDouglas Gregor 
138449a2790fSCraig Topper   clang::Module *Module = nullptr;
13855196bc6bSDouglas Gregor 
13865196bc6bSDouglas Gregor   // If we don't already have information on this module, load the module now.
1387de3ef502SDouglas Gregor   llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known
138869021974SDouglas Gregor     = KnownModules.find(Path[0].first);
13892537a364SDouglas Gregor   if (Known != KnownModules.end()) {
13902537a364SDouglas Gregor     // Retrieve the cached top-level module.
13912537a364SDouglas Gregor     Module = Known->second;
1392b537a3a6SBen Langmuir   } else if (ModuleName == getLangOpts().CurrentModule ||
1393b537a3a6SBen Langmuir              ModuleName == getLangOpts().ImplementationOfModule) {
13942537a364SDouglas Gregor     // This is the module we're building.
1395527040e0SBen Langmuir     Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
13962537a364SDouglas Gregor     Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
13972537a364SDouglas Gregor   } else {
13985196bc6bSDouglas Gregor     // Search for a module with the given name.
1399279a6c37SDouglas Gregor     Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
14009eb229bfSBen Langmuir     if (!Module) {
14019eb229bfSBen Langmuir       getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
14029eb229bfSBen Langmuir       << ModuleName
14039eb229bfSBen Langmuir       << SourceRange(ImportLoc, ModuleNameLoc);
14049eb229bfSBen Langmuir       ModuleBuildFailed = true;
14059eb229bfSBen Langmuir       return ModuleLoadResult();
14069eb229bfSBen Langmuir     }
14079eb229bfSBen Langmuir 
1408d4b230b3SRichard Smith     auto Override = ModuleFileOverrides.find(ModuleName);
1409d4b230b3SRichard Smith     bool Explicit = Override != ModuleFileOverrides.end();
1410d2e8b04dSManuel Klimek     if (!Explicit && !getLangOpts().ImplicitModules) {
1411d2e8b04dSManuel Klimek       getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled)
1412d2e8b04dSManuel Klimek           << ModuleName;
1413d2e8b04dSManuel Klimek       ModuleBuildFailed = true;
1414d2e8b04dSManuel Klimek       return ModuleLoadResult();
1415d2e8b04dSManuel Klimek     }
1416d4b230b3SRichard Smith 
1417f24d9c91SJustin Bogner     std::string ModuleFileName =
1418d4b230b3SRichard Smith         Explicit ? Override->second
1419d4b230b3SRichard Smith                  : PP->getHeaderSearchInfo().getModuleFileName(Module);
1420faeb1d46SDouglas Gregor 
142108142534SDouglas Gregor     // If we don't already have an ASTReader, create one now.
14222255f2ceSJohn Thompson     if (!ModuleManager)
14232255f2ceSJohn Thompson       createModuleManager();
142408142534SDouglas Gregor 
1425cb69b57bSBen Langmuir     if (TheDependencyFileGenerator)
1426cb69b57bSBen Langmuir       TheDependencyFileGenerator->AttachToASTReader(*ModuleManager);
1427cb69b57bSBen Langmuir 
142886d1259cSJustin Bogner     if (ModuleDepCollector)
142986d1259cSJustin Bogner       ModuleDepCollector->attachToASTReader(*ModuleManager);
143086d1259cSJustin Bogner 
143133c8090aSBen Langmuir     for (auto &Listener : DependencyCollectors)
143233c8090aSBen Langmuir       Listener->attachToASTReader(*ModuleManager);
143333c8090aSBen Langmuir 
14347029ce1aSDouglas Gregor     // Try to load the module file.
1435d4b230b3SRichard Smith     unsigned ARRFlags =
1436d4b230b3SRichard Smith         Explicit ? 0 : ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
1437e842a474SRichard Smith     switch (ModuleManager->ReadAST(ModuleFileName,
1438d4b230b3SRichard Smith                                    Explicit ? serialization::MK_ExplicitModule
1439d4b230b3SRichard Smith                                             : serialization::MK_ImplicitModule,
1440d4b230b3SRichard Smith                                    ImportLoc, ARRFlags)) {
144108142534SDouglas Gregor     case ASTReader::Success:
144208142534SDouglas Gregor       break;
144308142534SDouglas Gregor 
1444963ff2c3SEli Friedman     case ASTReader::OutOfDate:
14457029ce1aSDouglas Gregor     case ASTReader::Missing: {
1446d4b230b3SRichard Smith       if (Explicit) {
1447d4b230b3SRichard Smith         // ReadAST has already complained for us.
1448d4b230b3SRichard Smith         ModuleLoader::HadFatalFailure = true;
1449d4b230b3SRichard Smith         KnownModules[Path[0].first] = nullptr;
1450d4b230b3SRichard Smith         return ModuleLoadResult();
1451d4b230b3SRichard Smith       }
1452d4b230b3SRichard Smith 
1453963ff2c3SEli Friedman       // The module file is missing or out-of-date. Build it.
14549eb229bfSBen Langmuir       assert(Module && "missing module file");
14557029ce1aSDouglas Gregor       // Check whether there is a cycle in the module graph.
14567029ce1aSDouglas Gregor       ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack();
14577029ce1aSDouglas Gregor       ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
14587029ce1aSDouglas Gregor       for (; Pos != PosEnd; ++Pos) {
14597029ce1aSDouglas Gregor         if (Pos->first == ModuleName)
14607029ce1aSDouglas Gregor           break;
14617029ce1aSDouglas Gregor       }
14627029ce1aSDouglas Gregor 
14637029ce1aSDouglas Gregor       if (Pos != PosEnd) {
14647029ce1aSDouglas Gregor         SmallString<256> CyclePath;
14657029ce1aSDouglas Gregor         for (; Pos != PosEnd; ++Pos) {
14667029ce1aSDouglas Gregor           CyclePath += Pos->first;
14677029ce1aSDouglas Gregor           CyclePath += " -> ";
14687029ce1aSDouglas Gregor         }
14697029ce1aSDouglas Gregor         CyclePath += ModuleName;
14707029ce1aSDouglas Gregor 
14717029ce1aSDouglas Gregor         getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle)
14727029ce1aSDouglas Gregor           << ModuleName << CyclePath;
14737029ce1aSDouglas Gregor         return ModuleLoadResult();
14747029ce1aSDouglas Gregor       }
14757a626570SDouglas Gregor 
14767a626570SDouglas Gregor       // Check whether we have already attempted to build this module (but
14777a626570SDouglas Gregor       // failed).
14787a626570SDouglas Gregor       if (getPreprocessorOpts().FailedModules &&
14797a626570SDouglas Gregor           getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) {
14807a626570SDouglas Gregor         getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built)
14817a626570SDouglas Gregor           << ModuleName
14827a626570SDouglas Gregor           << SourceRange(ImportLoc, ModuleNameLoc);
1483c1bbec85SDouglas Gregor         ModuleBuildFailed = true;
14847a626570SDouglas Gregor         return ModuleLoadResult();
14857a626570SDouglas Gregor       }
14867a626570SDouglas Gregor 
1487dbdc0368SBen Langmuir       // Try to compile and then load the module.
1488dbdc0368SBen Langmuir       if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module,
1489dbdc0368SBen Langmuir                                 ModuleFileName)) {
1490d213aab7SBen Langmuir         assert(getDiagnostics().hasErrorOccurred() &&
1491d213aab7SBen Langmuir                "undiagnosed error in compileAndLoadModule");
14920f2b4635SDouglas Gregor         if (getPreprocessorOpts().FailedModules)
14937a626570SDouglas Gregor           getPreprocessorOpts().FailedModules->addFailed(ModuleName);
149449a2790fSCraig Topper         KnownModules[Path[0].first] = nullptr;
1495c1bbec85SDouglas Gregor         ModuleBuildFailed = true;
14967a626570SDouglas Gregor         return ModuleLoadResult();
1497188dbef2SDouglas Gregor       }
1498188dbef2SDouglas Gregor 
1499188dbef2SDouglas Gregor       // Okay, we've rebuilt and now loaded the module.
1500188dbef2SDouglas Gregor       break;
1501188dbef2SDouglas Gregor     }
1502188dbef2SDouglas Gregor 
1503c9ad5fb6SDouglas Gregor     case ASTReader::VersionMismatch:
1504c9ad5fb6SDouglas Gregor     case ASTReader::ConfigurationMismatch:
1505c9ad5fb6SDouglas Gregor     case ASTReader::HadErrors:
1506dc9fdaf2SArgyrios Kyrtzidis       ModuleLoader::HadFatalFailure = true;
150708142534SDouglas Gregor       // FIXME: The ASTReader will already have complained, but can we showhorn
150808142534SDouglas Gregor       // that diagnostic information into a more useful form?
150949a2790fSCraig Topper       KnownModules[Path[0].first] = nullptr;
15107a626570SDouglas Gregor       return ModuleLoadResult();
151108142534SDouglas Gregor 
151208142534SDouglas Gregor     case ASTReader::Failure:
1513dc9fdaf2SArgyrios Kyrtzidis       ModuleLoader::HadFatalFailure = true;
151469021974SDouglas Gregor       // Already complained, but note now that we failed.
151549a2790fSCraig Topper       KnownModules[Path[0].first] = nullptr;
1516c1bbec85SDouglas Gregor       ModuleBuildFailed = true;
15177a626570SDouglas Gregor       return ModuleLoadResult();
151808142534SDouglas Gregor     }
151908142534SDouglas Gregor 
152069021974SDouglas Gregor     // Cache the result of this top-level module lookup for later.
152169021974SDouglas Gregor     Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
152269021974SDouglas Gregor   }
152369021974SDouglas Gregor 
152469021974SDouglas Gregor   // If we never found the module, fail.
152569021974SDouglas Gregor   if (!Module)
15267a626570SDouglas Gregor     return ModuleLoadResult();
152769021974SDouglas Gregor 
15285196bc6bSDouglas Gregor   // Verify that the rest of the module path actually corresponds to
15295196bc6bSDouglas Gregor   // a submodule.
153069021974SDouglas Gregor   if (Path.size() > 1) {
15315196bc6bSDouglas Gregor     for (unsigned I = 1, N = Path.size(); I != N; ++I) {
15325196bc6bSDouglas Gregor       StringRef Name = Path[I].first->getName();
1533eb90e830SDouglas Gregor       clang::Module *Sub = Module->findSubmodule(Name);
15345196bc6bSDouglas Gregor 
1535eb90e830SDouglas Gregor       if (!Sub) {
15365196bc6bSDouglas Gregor         // Attempt to perform typo correction to find a module name that works.
1537f857950dSDmitri Gribenko         SmallVector<StringRef, 2> Best;
15385196bc6bSDouglas Gregor         unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
15395196bc6bSDouglas Gregor 
1540eb90e830SDouglas Gregor         for (clang::Module::submodule_iterator J = Module->submodule_begin(),
1541eb90e830SDouglas Gregor                                             JEnd = Module->submodule_end();
1542eb44edadSMatt Beaumont-Gay              J != JEnd; ++J) {
1543eb90e830SDouglas Gregor           unsigned ED = Name.edit_distance((*J)->Name,
15445196bc6bSDouglas Gregor                                            /*AllowReplacements=*/true,
15455196bc6bSDouglas Gregor                                            BestEditDistance);
15465196bc6bSDouglas Gregor           if (ED <= BestEditDistance) {
1547eb90e830SDouglas Gregor             if (ED < BestEditDistance) {
15485196bc6bSDouglas Gregor               Best.clear();
1549eb90e830SDouglas Gregor               BestEditDistance = ED;
1550eb90e830SDouglas Gregor             }
1551eb90e830SDouglas Gregor 
1552eb90e830SDouglas Gregor             Best.push_back((*J)->Name);
15535196bc6bSDouglas Gregor           }
15545196bc6bSDouglas Gregor         }
15555196bc6bSDouglas Gregor 
15565196bc6bSDouglas Gregor         // If there was a clear winner, user it.
15575196bc6bSDouglas Gregor         if (Best.size() == 1) {
15585196bc6bSDouglas Gregor           getDiagnostics().Report(Path[I].second,
15595196bc6bSDouglas Gregor                                   diag::err_no_submodule_suggest)
156069021974SDouglas Gregor             << Path[I].first << Module->getFullModuleName() << Best[0]
15615196bc6bSDouglas Gregor             << SourceRange(Path[0].second, Path[I-1].second)
15625196bc6bSDouglas Gregor             << FixItHint::CreateReplacement(SourceRange(Path[I].second),
15635196bc6bSDouglas Gregor                                             Best[0]);
1564eb90e830SDouglas Gregor 
1565eb90e830SDouglas Gregor           Sub = Module->findSubmodule(Best[0]);
15665196bc6bSDouglas Gregor         }
15675196bc6bSDouglas Gregor       }
15685196bc6bSDouglas Gregor 
1569eb90e830SDouglas Gregor       if (!Sub) {
15705196bc6bSDouglas Gregor         // No submodule by this name. Complain, and don't look for further
15715196bc6bSDouglas Gregor         // submodules.
15725196bc6bSDouglas Gregor         getDiagnostics().Report(Path[I].second, diag::err_no_submodule)
157369021974SDouglas Gregor           << Path[I].first << Module->getFullModuleName()
15745196bc6bSDouglas Gregor           << SourceRange(Path[0].second, Path[I-1].second);
15755196bc6bSDouglas Gregor         break;
15765196bc6bSDouglas Gregor       }
15775196bc6bSDouglas Gregor 
1578eb90e830SDouglas Gregor       Module = Sub;
15795196bc6bSDouglas Gregor     }
15805196bc6bSDouglas Gregor   }
15815196bc6bSDouglas Gregor 
1582b537a3a6SBen Langmuir   // Don't make the module visible if we are in the implementation.
1583b537a3a6SBen Langmuir   if (ModuleName == getLangOpts().ImplementationOfModule)
1584b537a3a6SBen Langmuir     return ModuleLoadResult(Module, false);
1585b537a3a6SBen Langmuir 
15862537a364SDouglas Gregor   // Make the named module visible, if it's not already part of the module
15872537a364SDouglas Gregor   // we are parsing.
158898a52db8SDouglas Gregor   if (ModuleName != getLangOpts().CurrentModule) {
158998a52db8SDouglas Gregor     if (!Module->IsFromModuleFile) {
159098a52db8SDouglas Gregor       // We have an umbrella header or directory that doesn't actually include
159198a52db8SDouglas Gregor       // all of the headers within the directory it covers. Complain about
159298a52db8SDouglas Gregor       // this missing submodule and recover by forgetting that we ever saw
159398a52db8SDouglas Gregor       // this submodule.
159498a52db8SDouglas Gregor       // FIXME: Should we detect this at module load time? It seems fairly
159598a52db8SDouglas Gregor       // expensive (and rare).
159698a52db8SDouglas Gregor       getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule)
159798a52db8SDouglas Gregor         << Module->getFullModuleName()
159898a52db8SDouglas Gregor         << SourceRange(Path.front().second, Path.back().second);
159998a52db8SDouglas Gregor 
160049a2790fSCraig Topper       return ModuleLoadResult(nullptr, true);
160198a52db8SDouglas Gregor     }
16021fb5c3a6SDouglas Gregor 
16031fb5c3a6SDouglas Gregor     // Check whether this module is available.
1604a3feee2aSRichard Smith     clang::Module::Requirement Requirement;
16053c1a41adSRichard Smith     clang::Module::UnresolvedHeaderDirective MissingHeader;
16060761a8a0SDaniel Jasper     if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement,
16070761a8a0SDaniel Jasper                              MissingHeader)) {
16080761a8a0SDaniel Jasper       if (MissingHeader.FileNameLoc.isValid()) {
16090761a8a0SDaniel Jasper         getDiagnostics().Report(MissingHeader.FileNameLoc,
16100761a8a0SDaniel Jasper                                 diag::err_module_header_missing)
16110761a8a0SDaniel Jasper           << MissingHeader.IsUmbrella << MissingHeader.FileName;
16120761a8a0SDaniel Jasper       } else {
16131fb5c3a6SDouglas Gregor         getDiagnostics().Report(ImportLoc, diag::err_module_unavailable)
16141fb5c3a6SDouglas Gregor           << Module->getFullModuleName()
1615a3feee2aSRichard Smith           << Requirement.second << Requirement.first
16161fb5c3a6SDouglas Gregor           << SourceRange(Path.front().second, Path.back().second);
16170761a8a0SDaniel Jasper       }
16181fb5c3a6SDouglas Gregor       LastModuleImportLoc = ImportLoc;
16197a626570SDouglas Gregor       LastModuleImportResult = ModuleLoadResult();
16207a626570SDouglas Gregor       return ModuleLoadResult();
16211fb5c3a6SDouglas Gregor     }
16221fb5c3a6SDouglas Gregor 
1623fb912657SDouglas Gregor     ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc,
1624fb912657SDouglas Gregor                                      /*Complain=*/true);
162598a52db8SDouglas Gregor   }
16265196bc6bSDouglas Gregor 
162735b13eceSDouglas Gregor   // Check for any configuration macros that have changed.
162835b13eceSDouglas Gregor   clang::Module *TopModule = Module->getTopLevelModule();
162935b13eceSDouglas Gregor   for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) {
163035b13eceSDouglas Gregor     checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I],
163135b13eceSDouglas Gregor                      Module, ImportLoc);
163235b13eceSDouglas Gregor   }
163335b13eceSDouglas Gregor 
16343c1a41adSRichard Smith   // Determine whether we're in the #include buffer for a module. The #includes
16353c1a41adSRichard Smith   // in that buffer do not qualify as module imports; they're just an
16363c1a41adSRichard Smith   // implementation detail of us building the module.
16373c1a41adSRichard Smith   bool IsInModuleIncludes = !getLangOpts().CurrentModule.empty() &&
16383c1a41adSRichard Smith                             getSourceManager().getFileID(ImportLoc) ==
16393c1a41adSRichard Smith                                 getSourceManager().getMainFileID();
16403c1a41adSRichard Smith 
1641bcfc7d02SDouglas Gregor   // If this module import was due to an inclusion directive, create an
1642bcfc7d02SDouglas Gregor   // implicit import declaration to capture it in the AST.
16433c1a41adSRichard Smith   if (IsInclusionDirective && hasASTContext() && !IsInModuleIncludes) {
1644bcfc7d02SDouglas Gregor     TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
164572d1aa3cSArgyrios Kyrtzidis     ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
1646bcfc7d02SDouglas Gregor                                                      ImportLoc, Module,
164772d1aa3cSArgyrios Kyrtzidis                                                      Path.back().second);
164872d1aa3cSArgyrios Kyrtzidis     TU->addDecl(ImportD);
164972d1aa3cSArgyrios Kyrtzidis     if (Consumer)
165072d1aa3cSArgyrios Kyrtzidis       Consumer->HandleImplicitImportDecl(ImportD);
1651bcfc7d02SDouglas Gregor   }
1652bcfc7d02SDouglas Gregor 
16531805b8a4SDouglas Gregor   LastModuleImportLoc = ImportLoc;
16547a626570SDouglas Gregor   LastModuleImportResult = ModuleLoadResult(Module, false);
16557a626570SDouglas Gregor   return LastModuleImportResult;
165608142534SDouglas Gregor }
1657c147b0bcSDouglas Gregor 
1658c147b0bcSDouglas Gregor void CompilerInstance::makeModuleVisible(Module *Mod,
1659125df058SArgyrios Kyrtzidis                                          Module::NameVisibilityKind Visibility,
1660fb912657SDouglas Gregor                                          SourceLocation ImportLoc,
1661fb912657SDouglas Gregor                                          bool Complain){
1662fb912657SDouglas Gregor   ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc, Complain);
1663c147b0bcSDouglas Gregor }
1664c147b0bcSDouglas Gregor 
16652255f2ceSJohn Thompson GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
16662255f2ceSJohn Thompson     SourceLocation TriggerLoc) {
16672255f2ceSJohn Thompson   if (!ModuleManager)
16682255f2ceSJohn Thompson     createModuleManager();
16692255f2ceSJohn Thompson   // Can't do anything if we don't have the module manager.
16702255f2ceSJohn Thompson   if (!ModuleManager)
167149a2790fSCraig Topper     return nullptr;
16722255f2ceSJohn Thompson   // Get an existing global index.  This loads it if not already
16732255f2ceSJohn Thompson   // loaded.
16742255f2ceSJohn Thompson   ModuleManager->loadGlobalIndex();
16752255f2ceSJohn Thompson   GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
16762255f2ceSJohn Thompson   // If the global index doesn't exist, create it.
16772255f2ceSJohn Thompson   if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() &&
16782255f2ceSJohn Thompson       hasPreprocessor()) {
16792255f2ceSJohn Thompson     llvm::sys::fs::create_directories(
16802255f2ceSJohn Thompson       getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
16812255f2ceSJohn Thompson     GlobalModuleIndex::writeIndex(
16822255f2ceSJohn Thompson       getFileManager(),
16832255f2ceSJohn Thompson       getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
16842255f2ceSJohn Thompson     ModuleManager->resetForReload();
16852255f2ceSJohn Thompson     ModuleManager->loadGlobalIndex();
16862255f2ceSJohn Thompson     GlobalIndex = ModuleManager->getGlobalIndex();
16872255f2ceSJohn Thompson   }
16882255f2ceSJohn Thompson   // For finding modules needing to be imported for fixit messages,
16892255f2ceSJohn Thompson   // we need to make the global index cover all modules, so we do that here.
16902255f2ceSJohn Thompson   if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) {
16912255f2ceSJohn Thompson     ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap();
16922255f2ceSJohn Thompson     bool RecreateIndex = false;
16932255f2ceSJohn Thompson     for (ModuleMap::module_iterator I = MMap.module_begin(),
16942255f2ceSJohn Thompson         E = MMap.module_end(); I != E; ++I) {
16952255f2ceSJohn Thompson       Module *TheModule = I->second;
16962255f2ceSJohn Thompson       const FileEntry *Entry = TheModule->getASTFile();
16972255f2ceSJohn Thompson       if (!Entry) {
16982255f2ceSJohn Thompson         SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
16992255f2ceSJohn Thompson         Path.push_back(std::make_pair(
17002255f2ceSJohn Thompson 				  getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc));
17012255f2ceSJohn Thompson         std::reverse(Path.begin(), Path.end());
17022255f2ceSJohn Thompson 		    // Load a module as hidden.  This also adds it to the global index.
1703e0a5afe8SJohn Thompson         loadModule(TheModule->DefinitionLoc, Path,
17042255f2ceSJohn Thompson                                              Module::Hidden, false);
17052255f2ceSJohn Thompson         RecreateIndex = true;
17062255f2ceSJohn Thompson       }
17072255f2ceSJohn Thompson     }
17082255f2ceSJohn Thompson     if (RecreateIndex) {
17092255f2ceSJohn Thompson       GlobalModuleIndex::writeIndex(
17102255f2ceSJohn Thompson         getFileManager(),
17112255f2ceSJohn Thompson         getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
17122255f2ceSJohn Thompson       ModuleManager->resetForReload();
17132255f2ceSJohn Thompson       ModuleManager->loadGlobalIndex();
17142255f2ceSJohn Thompson       GlobalIndex = ModuleManager->getGlobalIndex();
17152255f2ceSJohn Thompson     }
17162255f2ceSJohn Thompson     HaveFullGlobalModuleIndex = true;
17172255f2ceSJohn Thompson   }
17182255f2ceSJohn Thompson   return GlobalIndex;
17192255f2ceSJohn Thompson }
17202d94bbb0SJohn Thompson 
17212d94bbb0SJohn Thompson // Check global module index for missing imports.
17222d94bbb0SJohn Thompson bool
17232d94bbb0SJohn Thompson CompilerInstance::lookupMissingImports(StringRef Name,
17242d94bbb0SJohn Thompson                                        SourceLocation TriggerLoc) {
17252d94bbb0SJohn Thompson   // Look for the symbol in non-imported modules, but only if an error
17262d94bbb0SJohn Thompson   // actually occurred.
17272d94bbb0SJohn Thompson   if (!buildingModule()) {
17282d94bbb0SJohn Thompson     // Load global module index, or retrieve a previously loaded one.
17292d94bbb0SJohn Thompson     GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex(
17302d94bbb0SJohn Thompson       TriggerLoc);
17312d94bbb0SJohn Thompson 
17322d94bbb0SJohn Thompson     // Only if we have a global index.
17332d94bbb0SJohn Thompson     if (GlobalIndex) {
17342d94bbb0SJohn Thompson       GlobalModuleIndex::HitSet FoundModules;
17352d94bbb0SJohn Thompson 
17362d94bbb0SJohn Thompson       // Find the modules that reference the identifier.
17372d94bbb0SJohn Thompson       // Note that this only finds top-level modules.
17382d94bbb0SJohn Thompson       // We'll let diagnoseTypo find the actual declaration module.
17392d94bbb0SJohn Thompson       if (GlobalIndex->lookupIdentifier(Name, FoundModules))
17402d94bbb0SJohn Thompson         return true;
17412d94bbb0SJohn Thompson     }
17422d94bbb0SJohn Thompson   }
17432d94bbb0SJohn Thompson 
17442d94bbb0SJohn Thompson   return false;
17452d94bbb0SJohn Thompson }
1746a97eaa1bSDavid Blaikie void CompilerInstance::resetAndLeakSema() { BuryPointer(takeSema()); }
1747