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" 329670f847SMehdi Amini #include "clang/Lex/PreprocessorOptions.h" 33f7093b5aSDaniel Dunbar #include "clang/Sema/CodeCompleteConsumer.h" 343a02247dSChandler Carruth #include "clang/Sema/Sema.h" 353a02247dSChandler Carruth #include "clang/Serialization/ASTReader.h" 362255f2ceSJohn Thompson #include "clang/Serialization/GlobalModuleIndex.h" 37171b780cSDouglas Gregor #include "llvm/ADT/Statistic.h" 383a02247dSChandler Carruth #include "llvm/Support/CrashRecoveryContext.h" 3971de0b61SRafael Espindola #include "llvm/Support/Errc.h" 403a02247dSChandler Carruth #include "llvm/Support/FileSystem.h" 418aaf4995SMichael J. Spencer #include "llvm/Support/Host.h" 42e212489fSDouglas Gregor #include "llvm/Support/LockFileManager.h" 433a02247dSChandler Carruth #include "llvm/Support/MemoryBuffer.h" 448aaf4995SMichael J. Spencer #include "llvm/Support/Path.h" 458aaf4995SMichael J. Spencer #include "llvm/Support/Program.h" 468aaf4995SMichael J. Spencer #include "llvm/Support/Signals.h" 473a02247dSChandler Carruth #include "llvm/Support/Timer.h" 483a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 49527b1c95SDouglas Gregor #include <sys/stat.h> 508a8e554aSRafael Espindola #include <system_error> 5137da327cSDouglas Gregor #include <time.h> 52cfeacf56SBenjamin Kramer #include <utility> 5354a88810SDouglas Gregor 54636404a3SDaniel Dunbar using namespace clang; 55636404a3SDaniel Dunbar 56bb165fb0SAdrian Prantl CompilerInstance::CompilerInstance( 57bb165fb0SAdrian Prantl std::shared_ptr<PCHContainerOperations> PCHContainerOps, 58bb165fb0SAdrian Prantl bool BuildingModule) 59bb165fb0SAdrian Prantl : ModuleLoader(BuildingModule), Invocation(new CompilerInvocation()), 60cfeacf56SBenjamin Kramer ModuleManager(nullptr), 61cfeacf56SBenjamin Kramer ThePCHContainerOperations(std::move(PCHContainerOps)), 622255f2ceSJohn Thompson BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false), 63bb165fb0SAdrian Prantl ModuleBuildFailed(false) {} 64636404a3SDaniel Dunbar 65636404a3SDaniel Dunbar CompilerInstance::~CompilerInstance() { 663c717b45SBenjamin Kramer assert(OutputFiles.empty() && "Still output files in flight?"); 67e922d9bdSDaniel Dunbar } 68e922d9bdSDaniel Dunbar 6968242254SDaniel Dunbar void CompilerInstance::setInvocation(CompilerInvocation *Value) { 705e14d39aSTed Kremenek Invocation = Value; 7168242254SDaniel Dunbar } 7268242254SDaniel Dunbar 73c1bbec85SDouglas Gregor bool CompilerInstance::shouldBuildGlobalModuleIndex() const { 74e060e57bSDouglas Gregor return (BuildGlobalModuleIndex || 7511ef0b77SDouglas Gregor (ModuleManager && ModuleManager->isGlobalIndexUnavailable() && 7611ef0b77SDouglas Gregor getFrontendOpts().GenerateGlobalModuleIndex)) && 77e060e57bSDouglas Gregor !ModuleBuildFailed; 78c1bbec85SDouglas Gregor } 79c1bbec85SDouglas Gregor 809c902b55SDavid Blaikie void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) { 817f95d26eSDouglas Gregor Diagnostics = Value; 82e01dc86dSDaniel Dunbar } 83e01dc86dSDaniel Dunbar 84b5bc923aSArtem Belevich void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; } 85b5bc923aSArtem Belevich void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; } 86e01dc86dSDaniel Dunbar 87e01dc86dSDaniel Dunbar void CompilerInstance::setFileManager(FileManager *Value) { 885e14d39aSTed Kremenek FileMgr = Value; 89c8130a74SBen Langmuir if (Value) 90c8130a74SBen Langmuir VirtualFileSystem = Value->getVirtualFileSystem(); 91c8130a74SBen Langmuir else 92c8130a74SBen Langmuir VirtualFileSystem.reset(); 93e01dc86dSDaniel Dunbar } 94e01dc86dSDaniel Dunbar 95e01dc86dSDaniel Dunbar void CompilerInstance::setSourceManager(SourceManager *Value) { 965e14d39aSTed Kremenek SourceMgr = Value; 97e01dc86dSDaniel Dunbar } 98e01dc86dSDaniel Dunbar 995e14d39aSTed Kremenek void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; } 100e01dc86dSDaniel Dunbar 101293534b1SRichard Smith void CompilerInstance::setASTContext(ASTContext *Value) { 102293534b1SRichard Smith Context = Value; 103293534b1SRichard Smith 104293534b1SRichard Smith if (Context && Consumer) 105293534b1SRichard Smith getASTConsumer().Initialize(getASTContext()); 106293534b1SRichard Smith } 107e01dc86dSDaniel Dunbar 1080e93f017SDouglas Gregor void CompilerInstance::setSema(Sema *S) { 1090e93f017SDouglas Gregor TheSema.reset(S); 1100e93f017SDouglas Gregor } 1110e93f017SDouglas Gregor 1126beb6aa8SDavid Blaikie void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) { 1136beb6aa8SDavid Blaikie Consumer = std::move(Value); 114293534b1SRichard Smith 115293534b1SRichard Smith if (Context && Consumer) 116293534b1SRichard Smith getASTConsumer().Initialize(getASTContext()); 11756d9c293SDaniel Dunbar } 11856d9c293SDaniel Dunbar 119e01dc86dSDaniel Dunbar void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { 120e01dc86dSDaniel Dunbar CompletionConsumer.reset(Value); 121e01dc86dSDaniel Dunbar } 122e01dc86dSDaniel Dunbar 1236153581aSDavid Blaikie std::unique_ptr<Sema> CompilerInstance::takeSema() { 1246153581aSDavid Blaikie return std::move(TheSema); 1256153581aSDavid Blaikie } 1266153581aSDavid Blaikie 1271b7ed91eSArgyrios Kyrtzidis IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const { 1281b7ed91eSArgyrios Kyrtzidis return ModuleManager; 1291b7ed91eSArgyrios Kyrtzidis } 1301b7ed91eSArgyrios Kyrtzidis void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) { 131d6da1a09SBenjamin Kramer ModuleManager = std::move(Reader); 1321b7ed91eSArgyrios Kyrtzidis } 1331b7ed91eSArgyrios Kyrtzidis 13486d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector> 13586d1259cSJustin Bogner CompilerInstance::getModuleDepCollector() const { 13686d1259cSJustin Bogner return ModuleDepCollector; 13786d1259cSJustin Bogner } 13886d1259cSJustin Bogner 13986d1259cSJustin Bogner void CompilerInstance::setModuleDepCollector( 14086d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector> Collector) { 141d6da1a09SBenjamin Kramer ModuleDepCollector = std::move(Collector); 14286d1259cSJustin Bogner } 14386d1259cSJustin Bogner 1447d75afc5SDaniel Dunbar // Diagnostics 145811db4eaSDouglas Gregor static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, 1467b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts, 1479c902b55SDavid Blaikie DiagnosticsEngine &Diags) { 148dae941a6SRafael Espindola std::error_code EC; 14911f8a943SDavid Blaikie std::unique_ptr<raw_ostream> StreamOwner; 1500e62c1ccSChris Lattner raw_ostream *OS = &llvm::errs(); 151811db4eaSDouglas Gregor if (DiagOpts->DiagnosticLogFile != "-") { 1522083c32fSDaniel Dunbar // Create the output stream. 15311f8a943SDavid Blaikie auto FileOS = llvm::make_unique<llvm::raw_fd_ostream>( 154dae941a6SRafael Espindola DiagOpts->DiagnosticLogFile, EC, 15511f8a943SDavid Blaikie llvm::sys::fs::F_Append | llvm::sys::fs::F_Text); 156dae941a6SRafael Espindola if (EC) { 1572083c32fSDaniel Dunbar Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) 158dae941a6SRafael Espindola << DiagOpts->DiagnosticLogFile << EC.message(); 1592083c32fSDaniel Dunbar } else { 1602083c32fSDaniel Dunbar FileOS->SetUnbuffered(); 16111f8a943SDavid Blaikie OS = FileOS.get(); 16211f8a943SDavid Blaikie StreamOwner = std::move(FileOS); 1632083c32fSDaniel Dunbar } 1642083c32fSDaniel Dunbar } 1652083c32fSDaniel Dunbar 1662083c32fSDaniel Dunbar // Chain in the diagnostic client which will log the diagnostics. 1677ee25502SDavid Blaikie auto Logger = llvm::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts, 1687ee25502SDavid Blaikie std::move(StreamOwner)); 1697b83306dSDaniel Dunbar if (CodeGenOpts) 1707b83306dSDaniel Dunbar Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); 1717ee25502SDavid Blaikie assert(Diags.ownsClient()); 17241c247a6SAlexander Kornienko Diags.setClient( 17341c247a6SAlexander Kornienko new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger))); 1742083c32fSDaniel Dunbar } 1752083c32fSDaniel Dunbar 176811db4eaSDouglas Gregor static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, 1774610ea2bSTed Kremenek DiagnosticsEngine &Diags, 1784610ea2bSTed Kremenek StringRef OutputFile) { 1797ee25502SDavid Blaikie auto SerializedConsumer = 1805a6a2fcdSJustin Bogner clang::serialized_diags::create(OutputFile, DiagOpts); 1814610ea2bSTed Kremenek 182254b7dbaSAlexander Kornienko if (Diags.ownsClient()) { 1837ee25502SDavid Blaikie Diags.setClient(new ChainedDiagnosticConsumer( 18441c247a6SAlexander Kornienko Diags.takeClient(), std::move(SerializedConsumer))); 185254b7dbaSAlexander Kornienko } else { 186254b7dbaSAlexander Kornienko Diags.setClient(new ChainedDiagnosticConsumer( 1874c0ef379SAlexander Kornienko Diags.getClient(), std::move(SerializedConsumer))); 188254b7dbaSAlexander Kornienko } 1894610ea2bSTed Kremenek } 1904610ea2bSTed Kremenek 191f1b49e23SSean Silva void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client, 19230071ceaSDouglas Gregor bool ShouldOwnClient) { 193f1b49e23SSean Silva Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client, 19430071ceaSDouglas Gregor ShouldOwnClient, &getCodeGenOpts()); 1957d75afc5SDaniel Dunbar } 1967d75afc5SDaniel Dunbar 197c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 198811db4eaSDouglas Gregor CompilerInstance::createDiagnostics(DiagnosticOptions *Opts, 199e2eefaecSDavid Blaikie DiagnosticConsumer *Client, 2002b9b4642SDouglas Gregor bool ShouldOwnClient, 2017b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts) { 202c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 203c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 204811db4eaSDouglas Gregor Diags(new DiagnosticsEngine(DiagID, Opts)); 2051b39a2edSDaniel Dunbar 2067d75afc5SDaniel Dunbar // Create the diagnostic client for reporting errors or for 2077d75afc5SDaniel Dunbar // implementing -verify. 208d0e9e3a6SDouglas Gregor if (Client) { 209d0e9e3a6SDouglas Gregor Diags->setClient(Client, ShouldOwnClient); 210d0e9e3a6SDouglas Gregor } else 2112dd19f1dSDouglas Gregor Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); 21250ec0da0SDaniel Dunbar 21350ec0da0SDaniel Dunbar // Chain in -verify checker, if requested. 214811db4eaSDouglas Gregor if (Opts->VerifyDiagnostics) 21569609dceSDavid Blaikie Diags->setClient(new VerifyDiagnosticConsumer(*Diags)); 2167d75afc5SDaniel Dunbar 2172083c32fSDaniel Dunbar // Chain in -diagnostic-log-file dumper, if requested. 218811db4eaSDouglas Gregor if (!Opts->DiagnosticLogFile.empty()) 2197b83306dSDaniel Dunbar SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags); 2202083c32fSDaniel Dunbar 221811db4eaSDouglas Gregor if (!Opts->DiagnosticSerializationFile.empty()) 2224610ea2bSTed Kremenek SetupSerializedDiagnostics(Opts, *Diags, 223811db4eaSDouglas Gregor Opts->DiagnosticSerializationFile); 2244610ea2bSTed Kremenek 2257d75afc5SDaniel Dunbar // Configure our handling of diagnostics. 226811db4eaSDouglas Gregor ProcessWarningOptions(*Diags, *Opts); 2277d75afc5SDaniel Dunbar 2287f95d26eSDouglas Gregor return Diags; 2297d75afc5SDaniel Dunbar } 2307d75afc5SDaniel Dunbar 2317d75afc5SDaniel Dunbar // File Manager 2327d75afc5SDaniel Dunbar 233546a676aSDaniel Dunbar void CompilerInstance::createFileManager() { 234c8130a74SBen Langmuir if (!hasVirtualFileSystem()) { 235c8130a74SBen Langmuir // TODO: choose the virtual file system based on the CompilerInvocation. 236c8130a74SBen Langmuir setVirtualFileSystem(vfs::getRealFileSystem()); 237c8130a74SBen Langmuir } 238c8130a74SBen Langmuir FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem); 239546a676aSDaniel Dunbar } 240546a676aSDaniel Dunbar 2417d75afc5SDaniel Dunbar // Source Manager 2427d75afc5SDaniel Dunbar 2435159f616SChris Lattner void CompilerInstance::createSourceManager(FileManager &FileMgr) { 2445e14d39aSTed Kremenek SourceMgr = new SourceManager(getDiagnostics(), FileMgr); 245546a676aSDaniel Dunbar } 246aaa148fdSDaniel Dunbar 247c358000eSAlp Toker // Initialize the remapping of files to alternative contents, e.g., 248c358000eSAlp Toker // those specified through other files. 249c358000eSAlp Toker static void InitializeFileRemapping(DiagnosticsEngine &Diags, 250c358000eSAlp Toker SourceManager &SourceMgr, 251c358000eSAlp Toker FileManager &FileMgr, 252c358000eSAlp Toker const PreprocessorOptions &InitOpts) { 253c358000eSAlp Toker // Remap files in the source manager (with buffers). 2541b070d25SAlp Toker for (const auto &RB : InitOpts.RemappedFileBuffers) { 255c358000eSAlp Toker // Create the file entry for the file that we're mapping from. 256c358000eSAlp Toker const FileEntry *FromFile = 2571b070d25SAlp Toker FileMgr.getVirtualFile(RB.first, RB.second->getBufferSize(), 0); 258c358000eSAlp Toker if (!FromFile) { 2591b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_from_file) << RB.first; 260c358000eSAlp Toker if (!InitOpts.RetainRemappedFileBuffers) 2611b070d25SAlp Toker delete RB.second; 262c358000eSAlp Toker continue; 263c358000eSAlp Toker } 264c358000eSAlp Toker 265c358000eSAlp Toker // Override the contents of the "from" file with the contents of 266c358000eSAlp Toker // the "to" file. 2671b070d25SAlp Toker SourceMgr.overrideFileContents(FromFile, RB.second, 268c358000eSAlp Toker InitOpts.RetainRemappedFileBuffers); 269c358000eSAlp Toker } 270c358000eSAlp Toker 271c358000eSAlp Toker // Remap files in the source manager (with other files). 2721b070d25SAlp Toker for (const auto &RF : InitOpts.RemappedFiles) { 273c358000eSAlp Toker // Find the file that we're mapping to. 2741b070d25SAlp Toker const FileEntry *ToFile = FileMgr.getFile(RF.second); 275c358000eSAlp Toker if (!ToFile) { 2761b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second; 277c358000eSAlp Toker continue; 278c358000eSAlp Toker } 279c358000eSAlp Toker 280c358000eSAlp Toker // Create the file entry for the file that we're mapping from. 281c358000eSAlp Toker const FileEntry *FromFile = 2821b070d25SAlp Toker FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0); 283c358000eSAlp Toker if (!FromFile) { 2841b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first; 285c358000eSAlp Toker continue; 286c358000eSAlp Toker } 287c358000eSAlp Toker 288c358000eSAlp Toker // Override the contents of the "from" file with the contents of 289c358000eSAlp Toker // the "to" file. 290c358000eSAlp Toker SourceMgr.overrideFileContents(FromFile, ToFile); 291c358000eSAlp Toker } 292c358000eSAlp Toker 293c358000eSAlp Toker SourceMgr.setOverridenFilesKeepOriginalName( 294c358000eSAlp Toker InitOpts.RemappedFilesKeepOriginalName); 295c358000eSAlp Toker } 296c358000eSAlp Toker 2977d75afc5SDaniel Dunbar // Preprocessor 2987d75afc5SDaniel Dunbar 299e1974dcdSArgyrios Kyrtzidis void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { 30008142534SDouglas Gregor const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 301aaa148fdSDaniel Dunbar 302aaa148fdSDaniel Dunbar // Create a PTH manager if we are using some form of a token cache. 30349a2790fSCraig Topper PTHManager *PTHMgr = nullptr; 304d6ea9028SDaniel Dunbar if (!PPOpts.TokenCache.empty()) 30508142534SDouglas Gregor PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics()); 306aaa148fdSDaniel Dunbar 307aaa148fdSDaniel Dunbar // Create the Preprocessor. 308b85b9ccbSDouglas Gregor HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(), 3091f76c4e8SManuel Klimek getSourceManager(), 3101fb5c3a6SDouglas Gregor getDiagnostics(), 31189929282SDouglas Gregor getLangOpts(), 31289929282SDouglas Gregor &getTarget()); 3139663780eSAlp Toker PP = new Preprocessor(&getPreprocessorOpts(), getDiagnostics(), getLangOpts(), 31408142534SDouglas Gregor getSourceManager(), *HeaderInfo, *this, PTHMgr, 3159663780eSAlp Toker /*OwnsHeaderSearch=*/true, TUKind); 316b5bc923aSArtem Belevich PP->Initialize(getTarget(), getAuxTarget()); 317aaa148fdSDaniel Dunbar 318aaa148fdSDaniel Dunbar // Note that this is different then passing PTHMgr to Preprocessor's ctor. 319aaa148fdSDaniel Dunbar // That argument is used as the IdentifierInfoLookup argument to 320aaa148fdSDaniel Dunbar // IdentifierTable's ctor. 321aaa148fdSDaniel Dunbar if (PTHMgr) { 32208142534SDouglas Gregor PTHMgr->setPreprocessor(&*PP); 323aaa148fdSDaniel Dunbar PP->setPTHManager(PTHMgr); 324aaa148fdSDaniel Dunbar } 325aaa148fdSDaniel Dunbar 3267f6d60dcSDouglas Gregor if (PPOpts.DetailedRecord) 327f3d587eaSArgyrios Kyrtzidis PP->createPreprocessingRecord(); 3287f6d60dcSDouglas Gregor 329c358000eSAlp Toker // Apply remappings to the source manager. 330c358000eSAlp Toker InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(), 331c358000eSAlp Toker PP->getFileManager(), PPOpts); 332c358000eSAlp Toker 333c358000eSAlp Toker // Predefine macros and configure the preprocessor. 334fb2398d0SAdrian Prantl InitializePreprocessor(*PP, PPOpts, getPCHContainerReader(), 335bb165fb0SAdrian Prantl getFrontendOpts()); 336c358000eSAlp Toker 337c358000eSAlp Toker // Initialize the header search object. 338c358000eSAlp Toker ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(), 339c358000eSAlp Toker PP->getLangOpts(), PP->getTargetInfo().getTriple()); 340aaa148fdSDaniel Dunbar 34117441589SJordan Rose PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP); 34217441589SJordan Rose 3433938f0c7SRichard Smith if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) 344bd0b651bSArgyrios Kyrtzidis PP->getHeaderSearchInfo().setModuleCachePath(getSpecificModuleCachePath()); 3451735f4e7SDouglas Gregor 346aaa148fdSDaniel Dunbar // Handle generating dependencies, if requested. 34708142534SDouglas Gregor const DependencyOutputOptions &DepOpts = getDependencyOutputOpts(); 348aaa148fdSDaniel Dunbar if (!DepOpts.OutputFile.empty()) 349cb69b57bSBen Langmuir TheDependencyFileGenerator.reset( 350cb69b57bSBen Langmuir DependencyFileGenerator::CreateAndAttachToPreprocessor(*PP, DepOpts)); 3512e129659SDouglas Gregor if (!DepOpts.DOTOutputFile.empty()) 3522e129659SDouglas Gregor AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, 35383d46be3SDouglas Gregor getHeaderSearchOpts().Sysroot); 35483d46be3SDouglas Gregor 35586d1259cSJustin Bogner // If we don't have a collector, but we are collecting module dependencies, 35686d1259cSJustin Bogner // then we're the top level compiler instance and need to create one. 357b1631d91SBruno Cardoso Lopes if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty()) { 35886d1259cSJustin Bogner ModuleDepCollector = std::make_shared<ModuleDependencyCollector>( 35986d1259cSJustin Bogner DepOpts.ModuleDependencyOutputDir); 360b1631d91SBruno Cardoso Lopes } 361b1631d91SBruno Cardoso Lopes 362b1631d91SBruno Cardoso Lopes if (ModuleDepCollector) 363b1631d91SBruno Cardoso Lopes addDependencyCollector(ModuleDepCollector); 364b1631d91SBruno Cardoso Lopes 365b1631d91SBruno Cardoso Lopes for (auto &Listener : DependencyCollectors) 366b1631d91SBruno Cardoso Lopes Listener->attachToPreprocessor(*PP); 367aaa148fdSDaniel Dunbar 36827734fdbSDaniel Dunbar // Handle generating header include information, if requested. 36927734fdbSDaniel Dunbar if (DepOpts.ShowHeaderIncludes) 370f54146c1SNico Weber AttachHeaderIncludeGen(*PP, DepOpts); 3711af1d275SDaniel Dunbar if (!DepOpts.HeaderIncludeOutputFile.empty()) { 3720e62c1ccSChris Lattner StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; 3731af1d275SDaniel Dunbar if (OutputPath == "-") 3741af1d275SDaniel Dunbar OutputPath = ""; 375f54146c1SNico Weber AttachHeaderIncludeGen(*PP, DepOpts, 3761193f2cbSIvan Krasin /*ShowAllHeaders=*/true, OutputPath, 377fe908a80SDaniel Dunbar /*ShowDepth=*/false); 3780fd6207dSHans Wennborg } 3790fd6207dSHans Wennborg 3800fd6207dSHans Wennborg if (DepOpts.PrintShowIncludes) { 381f54146c1SNico Weber AttachHeaderIncludeGen(*PP, DepOpts, 382149d9522SNico Weber /*ShowAllHeaders=*/true, /*OutputPath=*/"", 3830fd6207dSHans Wennborg /*ShowDepth=*/true, /*MSStyle=*/true); 3841af1d275SDaniel Dunbar } 385aaa148fdSDaniel Dunbar } 386df3e30c4SDaniel Dunbar 387bd0b651bSArgyrios Kyrtzidis std::string CompilerInstance::getSpecificModuleCachePath() { 388bd0b651bSArgyrios Kyrtzidis // Set up the module path, including the hash for the 389bd0b651bSArgyrios Kyrtzidis // module-creation options. 390d520a250SRichard Smith SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath); 391d520a250SRichard Smith if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash) 392bd0b651bSArgyrios Kyrtzidis llvm::sys::path::append(SpecificModuleCache, 393bd0b651bSArgyrios Kyrtzidis getInvocation().getModuleHash()); 394bd0b651bSArgyrios Kyrtzidis return SpecificModuleCache.str(); 395bd0b651bSArgyrios Kyrtzidis } 396bd0b651bSArgyrios Kyrtzidis 397df3e30c4SDaniel Dunbar // ASTContext 398df3e30c4SDaniel Dunbar 399df3e30c4SDaniel Dunbar void CompilerInstance::createASTContext() { 400df3e30c4SDaniel Dunbar Preprocessor &PP = getPreprocessor(); 401293534b1SRichard Smith auto *Context = new ASTContext(getLangOpts(), PP.getSourceManager(), 40208043437SAlp Toker PP.getIdentifierTable(), PP.getSelectorTable(), 40308043437SAlp Toker PP.getBuiltinInfo()); 404b5bc923aSArtem Belevich Context->InitBuiltinTypes(getTarget(), getAuxTarget()); 405293534b1SRichard Smith setASTContext(Context); 406df3e30c4SDaniel Dunbar } 407599313efSDaniel Dunbar 408599313efSDaniel Dunbar // ExternalASTSource 409599313efSDaniel Dunbar 410824285ecSNico Weber void CompilerInstance::createPCHExternalASTSource( 411824285ecSNico Weber StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, 412824285ecSNico Weber void *DeserializationListener, bool OwnDeserializationListener) { 413009e7f20SSebastian Redl bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; 4144eca9b93SRichard Smith ModuleManager = createPCHExternalASTSource( 415824285ecSNico Weber Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, 416824285ecSNico Weber AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(), 4176623e1f1SDouglas Gregor getPCHContainerReader(), 4186623e1f1SDouglas Gregor getFrontendOpts().ModuleFileExtensions, 4196623e1f1SDouglas Gregor DeserializationListener, 420bb165fb0SAdrian Prantl OwnDeserializationListener, Preamble, 4211b7ed91eSArgyrios Kyrtzidis getFrontendOpts().UseGlobalModuleIndex); 422599313efSDaniel Dunbar } 423599313efSDaniel Dunbar 4244eca9b93SRichard Smith IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( 4255b816061SYaron Keren StringRef Path, StringRef Sysroot, bool DisablePCHValidation, 426824285ecSNico Weber bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, 427fb2398d0SAdrian Prantl const PCHContainerReader &PCHContainerRdr, 4286623e1f1SDouglas Gregor ArrayRef<IntrusiveRefCntPtr<ModuleFileExtension>> Extensions, 429824285ecSNico Weber void *DeserializationListener, bool OwnDeserializationListener, 430824285ecSNico Weber bool Preamble, bool UseGlobalModuleIndex) { 431dcf73861SBen Langmuir HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); 432dcf73861SBen Langmuir 433bb165fb0SAdrian Prantl IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader( 4346623e1f1SDouglas Gregor PP, Context, PCHContainerRdr, Extensions, 4356623e1f1SDouglas Gregor Sysroot.empty() ? "" : Sysroot.data(), DisablePCHValidation, 4366623e1f1SDouglas Gregor AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false, 4376623e1f1SDouglas Gregor HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex)); 4384eca9b93SRichard Smith 4394eca9b93SRichard Smith // We need the external source to be set up before we read the AST, because 4404eca9b93SRichard Smith // eagerly-deserialized declarations may use it. 4414eca9b93SRichard Smith Context.setExternalSource(Reader.get()); 442599313efSDaniel Dunbar 44307a89a83SSebastian Redl Reader->setDeserializationListener( 444824285ecSNico Weber static_cast<ASTDeserializationListener *>(DeserializationListener), 445824285ecSNico Weber /*TakeOwnership=*/OwnDeserializationListener); 446009e7f20SSebastian Redl switch (Reader->ReadAST(Path, 447a6895d8aSDouglas Gregor Preamble ? serialization::MK_Preamble 4484b29c16eSDouglas Gregor : serialization::MK_PCH, 4492ec29367SArgyrios Kyrtzidis SourceLocation(), 4503d4417c7SBen Langmuir ASTReader::ARR_None)) { 4512c499f65SSebastian Redl case ASTReader::Success: 452599313efSDaniel Dunbar // Set the predefines buffer as suggested by the PCH reader. Typically, the 453599313efSDaniel Dunbar // predefines buffer will be empty. 454599313efSDaniel Dunbar PP.setPredefines(Reader->getSuggestedPredefines()); 4554eca9b93SRichard Smith return Reader; 456599313efSDaniel Dunbar 4572c499f65SSebastian Redl case ASTReader::Failure: 458599313efSDaniel Dunbar // Unrecoverable failure: don't even try to process the input file. 459599313efSDaniel Dunbar break; 460599313efSDaniel Dunbar 4617029ce1aSDouglas Gregor case ASTReader::Missing: 462c9ad5fb6SDouglas Gregor case ASTReader::OutOfDate: 463c9ad5fb6SDouglas Gregor case ASTReader::VersionMismatch: 464c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 465c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 466599313efSDaniel Dunbar // No suitable PCH file could be found. Return an error. 467599313efSDaniel Dunbar break; 468599313efSDaniel Dunbar } 469599313efSDaniel Dunbar 4704eca9b93SRichard Smith Context.setExternalSource(nullptr); 47149a2790fSCraig Topper return nullptr; 472599313efSDaniel Dunbar } 473f7093b5aSDaniel Dunbar 474f7093b5aSDaniel Dunbar // Code Completion 475f7093b5aSDaniel Dunbar 4768e984da8SDouglas Gregor static bool EnableCodeCompletion(Preprocessor &PP, 4770772c423SBenjamin Kramer StringRef Filename, 4788e984da8SDouglas Gregor unsigned Line, 4798e984da8SDouglas Gregor unsigned Column) { 4808e984da8SDouglas Gregor // Tell the source manager to chop off the given file at a specific 4818e984da8SDouglas Gregor // line and column. 4825159f616SChris Lattner const FileEntry *Entry = PP.getFileManager().getFile(Filename); 4838e984da8SDouglas Gregor if (!Entry) { 4848e984da8SDouglas Gregor PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) 4858e984da8SDouglas Gregor << Filename; 4868e984da8SDouglas Gregor return true; 4878e984da8SDouglas Gregor } 4888e984da8SDouglas Gregor 4898e984da8SDouglas Gregor // Truncate the named file at the given line/column. 4908e984da8SDouglas Gregor PP.SetCodeCompletionPoint(Entry, Line, Column); 4918e984da8SDouglas Gregor return false; 4928e984da8SDouglas Gregor } 4938e984da8SDouglas Gregor 494f7093b5aSDaniel Dunbar void CompilerInstance::createCodeCompletionConsumer() { 495f7093b5aSDaniel Dunbar const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt; 4968e984da8SDouglas Gregor if (!CompletionConsumer) { 4972fca3c2cSErik Verbruggen setCodeCompletionConsumer( 498f7093b5aSDaniel Dunbar createCodeCompletionConsumer(getPreprocessor(), 499f7093b5aSDaniel Dunbar Loc.FileName, Loc.Line, Loc.Column, 5003292d06aSDmitri Gribenko getFrontendOpts().CodeCompleteOpts, 501f7093b5aSDaniel Dunbar llvm::outs())); 50200a0cf70SDouglas Gregor if (!CompletionConsumer) 50300a0cf70SDouglas Gregor return; 5048e984da8SDouglas Gregor } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName, 5058e984da8SDouglas Gregor Loc.Line, Loc.Column)) { 50649a2790fSCraig Topper setCodeCompletionConsumer(nullptr); 5078e984da8SDouglas Gregor return; 5088e984da8SDouglas Gregor } 509f09935f1SDouglas Gregor 510f09935f1SDouglas Gregor if (CompletionConsumer->isOutputBinary() && 511a3346d87SRafael Espindola llvm::sys::ChangeStdoutToBinary()) { 512f09935f1SDouglas Gregor getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary); 51349a2790fSCraig Topper setCodeCompletionConsumer(nullptr); 514f09935f1SDouglas Gregor } 515f7093b5aSDaniel Dunbar } 516f7093b5aSDaniel Dunbar 5175505dff8SKovarththanan Rajaratnam void CompilerInstance::createFrontendTimer() { 518ce18a187SRichard Smith FrontendTimerGroup.reset(new llvm::TimerGroup("Clang front-end time report")); 519ce18a187SRichard Smith FrontendTimer.reset( 520ce18a187SRichard Smith new llvm::Timer("Clang front-end timer", *FrontendTimerGroup)); 5215505dff8SKovarththanan Rajaratnam } 5225505dff8SKovarththanan Rajaratnam 523f7093b5aSDaniel Dunbar CodeCompleteConsumer * 524f7093b5aSDaniel Dunbar CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP, 5255b816061SYaron Keren StringRef Filename, 526f7093b5aSDaniel Dunbar unsigned Line, 527f7093b5aSDaniel Dunbar unsigned Column, 5283292d06aSDmitri Gribenko const CodeCompleteOptions &Opts, 5290e62c1ccSChris Lattner raw_ostream &OS) { 5308e984da8SDouglas Gregor if (EnableCodeCompletion(PP, Filename, Line, Column)) 53149a2790fSCraig Topper return nullptr; 532f7093b5aSDaniel Dunbar 533f7093b5aSDaniel Dunbar // Set up the creation routine for code-completion. 5343292d06aSDmitri Gribenko return new PrintingCodeCompleteConsumer(Opts, OS); 535f7093b5aSDaniel Dunbar } 536566eeb2dSDaniel Dunbar 53769f74f80SDouglas Gregor void CompilerInstance::createSema(TranslationUnitKind TUKind, 5380e93f017SDouglas Gregor CodeCompleteConsumer *CompletionConsumer) { 5390e93f017SDouglas Gregor TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(), 54069f74f80SDouglas Gregor TUKind, CompletionConsumer)); 5410e93f017SDouglas Gregor } 5420e93f017SDouglas Gregor 543566eeb2dSDaniel Dunbar // Output Files 544566eeb2dSDaniel Dunbar 545269ec0f4SRafael Espindola void CompilerInstance::addOutputFile(OutputFile &&OutFile) { 546269ec0f4SRafael Espindola OutputFiles.push_back(std::move(OutFile)); 547566eeb2dSDaniel Dunbar } 548566eeb2dSDaniel Dunbar 5491c558cd7SKovarththanan Rajaratnam void CompilerInstance::clearOutputFiles(bool EraseFiles) { 5500aa128e2SReid Kleckner for (OutputFile &OF : OutputFiles) { 5510aa128e2SReid Kleckner if (!OF.TempFilename.empty()) { 552b5c356a4SAnders Carlsson if (EraseFiles) { 5530aa128e2SReid Kleckner llvm::sys::fs::remove(OF.TempFilename); 554b5c356a4SAnders Carlsson } else { 5550aa128e2SReid Kleckner SmallString<128> NewOutFile(OF.Filename); 556b5c356a4SAnders Carlsson 55771731d6bSArgyrios Kyrtzidis // If '-working-directory' was passed, the output filename should be 55871731d6bSArgyrios Kyrtzidis // relative to that. 5599ba8fb1eSAnders Carlsson FileMgr->FixupRelativePath(NewOutFile); 560c080917eSRafael Espindola if (std::error_code ec = 5610aa128e2SReid Kleckner llvm::sys::fs::rename(OF.TempFilename, NewOutFile)) { 5623ef9c447SManuel Klimek getDiagnostics().Report(diag::err_unable_to_rename_temp) 5630aa128e2SReid Kleckner << OF.TempFilename << OF.Filename << ec.message(); 564b5c356a4SAnders Carlsson 5650aa128e2SReid Kleckner llvm::sys::fs::remove(OF.TempFilename); 566d0599970SArgyrios Kyrtzidis } 567d0599970SArgyrios Kyrtzidis } 5680aa128e2SReid Kleckner } else if (!OF.Filename.empty() && EraseFiles) 5690aa128e2SReid Kleckner llvm::sys::fs::remove(OF.Filename); 570566eeb2dSDaniel Dunbar } 571566eeb2dSDaniel Dunbar OutputFiles.clear(); 5722f16bc10SRafael Espindola NonSeekStream.reset(); 573566eeb2dSDaniel Dunbar } 574566eeb2dSDaniel Dunbar 57503f8907fSPeter Collingbourne std::unique_ptr<raw_pwrite_stream> 5762f16bc10SRafael Espindola CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile, 5770e62c1ccSChris Lattner StringRef Extension) { 578420b0f1bSDaniel Dunbar return createOutputFile(getFrontendOpts().OutputFile, Binary, 579ae77b3dfSDaniel Dunbar /*RemoveFileOnSignal=*/true, InFile, Extension, 580ae77b3dfSDaniel Dunbar /*UseTemporary=*/true); 581420b0f1bSDaniel Dunbar } 582420b0f1bSDaniel Dunbar 58303f8907fSPeter Collingbourne std::unique_ptr<raw_pwrite_stream> CompilerInstance::createNullOutputFile() { 58403f8907fSPeter Collingbourne return llvm::make_unique<llvm::raw_null_ostream>(); 585ea04672cSAlp Toker } 586ea04672cSAlp Toker 58703f8907fSPeter Collingbourne std::unique_ptr<raw_pwrite_stream> 5882f16bc10SRafael Espindola CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary, 5892f16bc10SRafael Espindola bool RemoveFileOnSignal, StringRef InFile, 5902f16bc10SRafael Espindola StringRef Extension, bool UseTemporary, 591b9c62c07SDaniel Dunbar bool CreateMissingDirectories) { 592dae941a6SRafael Espindola std::string OutputPathName, TempPathName; 593dae941a6SRafael Espindola std::error_code EC; 5942f16bc10SRafael Espindola std::unique_ptr<raw_pwrite_stream> OS = createOutputFile( 595dae941a6SRafael Espindola OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension, 596c80a4066SRafael Espindola UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName); 597420b0f1bSDaniel Dunbar if (!OS) { 598dae941a6SRafael Espindola getDiagnostics().Report(diag::err_fe_unable_to_open_output) << OutputPath 599dae941a6SRafael Espindola << EC.message(); 60049a2790fSCraig Topper return nullptr; 601420b0f1bSDaniel Dunbar } 602420b0f1bSDaniel Dunbar 603420b0f1bSDaniel Dunbar // Add the output file -- but don't try to remove "-", since this means we are 604420b0f1bSDaniel Dunbar // using stdin. 60503f8907fSPeter Collingbourne addOutputFile( 60603f8907fSPeter Collingbourne OutputFile((OutputPathName != "-") ? OutputPathName : "", TempPathName)); 607420b0f1bSDaniel Dunbar 60803f8907fSPeter Collingbourne return OS; 609420b0f1bSDaniel Dunbar } 610420b0f1bSDaniel Dunbar 6112f16bc10SRafael Espindola std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile( 612dae941a6SRafael Espindola StringRef OutputPath, std::error_code &Error, bool Binary, 613dae941a6SRafael Espindola bool RemoveFileOnSignal, StringRef InFile, StringRef Extension, 614dae941a6SRafael Espindola bool UseTemporary, bool CreateMissingDirectories, 615dae941a6SRafael Espindola std::string *ResultPathName, std::string *TempPathName) { 616b9c62c07SDaniel Dunbar assert((!CreateMissingDirectories || UseTemporary) && 617b9c62c07SDaniel Dunbar "CreateMissingDirectories is only allowed when using temporary files"); 618b9c62c07SDaniel Dunbar 619d0599970SArgyrios Kyrtzidis std::string OutFile, TempFile; 620420b0f1bSDaniel Dunbar if (!OutputPath.empty()) { 621420b0f1bSDaniel Dunbar OutFile = OutputPath; 622420b0f1bSDaniel Dunbar } else if (InFile == "-") { 623420b0f1bSDaniel Dunbar OutFile = "-"; 624420b0f1bSDaniel Dunbar } else if (!Extension.empty()) { 625399ab33aSRafael Espindola SmallString<128> Path(InFile); 626399ab33aSRafael Espindola llvm::sys::path::replace_extension(Path, Extension); 627420b0f1bSDaniel Dunbar OutFile = Path.str(); 628420b0f1bSDaniel Dunbar } else { 629420b0f1bSDaniel Dunbar OutFile = "-"; 630420b0f1bSDaniel Dunbar } 631420b0f1bSDaniel Dunbar 632b8984329SAhmed Charles std::unique_ptr<llvm::raw_fd_ostream> OS; 63308a2bfd2SArgyrios Kyrtzidis std::string OSFile; 63408a2bfd2SArgyrios Kyrtzidis 63573c23a71SRafael Espindola if (UseTemporary) { 63673c23a71SRafael Espindola if (OutFile == "-") 63773c23a71SRafael Espindola UseTemporary = false; 63873c23a71SRafael Espindola else { 63973c23a71SRafael Espindola llvm::sys::fs::file_status Status; 64073c23a71SRafael Espindola llvm::sys::fs::status(OutputPath, Status); 64173c23a71SRafael Espindola if (llvm::sys::fs::exists(Status)) { 64273c23a71SRafael Espindola // Fail early if we can't write to the final destination. 6438bfac2c5SDouglas Katzman if (!llvm::sys::fs::can_write(OutputPath)) { 644ee4e08baSRafael Espindola Error = make_error_code(llvm::errc::operation_not_permitted); 64549a2790fSCraig Topper return nullptr; 6468bfac2c5SDouglas Katzman } 64773c23a71SRafael Espindola 64873c23a71SRafael Espindola // Don't use a temporary if the output is a special file. This handles 64973c23a71SRafael Espindola // things like '-o /dev/null' 65073c23a71SRafael Espindola if (!llvm::sys::fs::is_regular_file(Status)) 65173c23a71SRafael Espindola UseTemporary = false; 65273c23a71SRafael Espindola } 65373c23a71SRafael Espindola } 65473c23a71SRafael Espindola } 65573c23a71SRafael Espindola 65673c23a71SRafael Espindola if (UseTemporary) { 657d0599970SArgyrios Kyrtzidis // Create a temporary file. 6582c1dd271SDylan Noblesmith SmallString<128> TempPath; 65908a2bfd2SArgyrios Kyrtzidis TempPath = OutFile; 66008a2bfd2SArgyrios Kyrtzidis TempPath += "-%%%%%%%%"; 66108a2bfd2SArgyrios Kyrtzidis int fd; 662c080917eSRafael Espindola std::error_code EC = 66392e1b62dSYaron Keren llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath); 664157f34bdSRafael Espindola 665157f34bdSRafael Espindola if (CreateMissingDirectories && 66671de0b61SRafael Espindola EC == llvm::errc::no_such_file_or_directory) { 667157f34bdSRafael Espindola StringRef Parent = llvm::sys::path::parent_path(OutputPath); 668157f34bdSRafael Espindola EC = llvm::sys::fs::create_directories(Parent); 669157f34bdSRafael Espindola if (!EC) { 67092e1b62dSYaron Keren EC = llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath); 671157f34bdSRafael Espindola } 672157f34bdSRafael Espindola } 673157f34bdSRafael Espindola 674157f34bdSRafael Espindola if (!EC) { 67569f3528cSNAKAMURA Takumi OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); 67608a2bfd2SArgyrios Kyrtzidis OSFile = TempFile = TempPath.str(); 67708a2bfd2SArgyrios Kyrtzidis } 67873c23a71SRafael Espindola // If we failed to create the temporary, fallback to writing to the file 67973c23a71SRafael Espindola // directly. This handles the corner case where we cannot write to the 68073c23a71SRafael Espindola // directory, but can write to the file. 681d0599970SArgyrios Kyrtzidis } 682d0599970SArgyrios Kyrtzidis 68308a2bfd2SArgyrios Kyrtzidis if (!OS) { 68408a2bfd2SArgyrios Kyrtzidis OSFile = OutFile; 68569f3528cSNAKAMURA Takumi OS.reset(new llvm::raw_fd_ostream( 686dae941a6SRafael Espindola OSFile, Error, 68769f3528cSNAKAMURA Takumi (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text))); 688dae941a6SRafael Espindola if (Error) 68949a2790fSCraig Topper return nullptr; 69008a2bfd2SArgyrios Kyrtzidis } 691420b0f1bSDaniel Dunbar 692d0599970SArgyrios Kyrtzidis // Make sure the out stream file gets removed if we crash. 693e326f9bbSDaniel Dunbar if (RemoveFileOnSignal) 69418556de3SRafael Espindola llvm::sys::RemoveFileOnSignal(OSFile); 695d0599970SArgyrios Kyrtzidis 696420b0f1bSDaniel Dunbar if (ResultPathName) 697420b0f1bSDaniel Dunbar *ResultPathName = OutFile; 698d0599970SArgyrios Kyrtzidis if (TempPathName) 699d0599970SArgyrios Kyrtzidis *TempPathName = TempFile; 700420b0f1bSDaniel Dunbar 7012f16bc10SRafael Espindola if (!Binary || OS->supportsSeeking()) 7022f16bc10SRafael Espindola return std::move(OS); 7032f16bc10SRafael Espindola 7042f16bc10SRafael Espindola auto B = llvm::make_unique<llvm::buffer_ostream>(*OS); 7052f16bc10SRafael Espindola assert(!NonSeekStream); 7062f16bc10SRafael Espindola NonSeekStream = std::move(OS); 7072f16bc10SRafael Espindola return std::move(B); 708420b0f1bSDaniel Dunbar } 709409e890fSDaniel Dunbar 710409e890fSDaniel Dunbar // Initialization Utilities 711409e890fSDaniel Dunbar 7121b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ 7132ca4be97SNico Weber return InitializeSourceManager( 7142ca4be97SNico Weber Input, getDiagnostics(), getFileManager(), getSourceManager(), 7152ca4be97SNico Weber hasPreprocessor() ? &getPreprocessor().getHeaderSearchInfo() : nullptr, 7164b5aedefSNico Weber getDependencyOutputOpts(), getFrontendOpts()); 717409e890fSDaniel Dunbar } 718409e890fSDaniel Dunbar 7192ca4be97SNico Weber // static 7204b5aedefSNico Weber bool CompilerInstance::InitializeSourceManager( 7214b5aedefSNico Weber const FrontendInputFile &Input, DiagnosticsEngine &Diags, 7224b5aedefSNico Weber FileManager &FileMgr, SourceManager &SourceMgr, HeaderSearch *HS, 7234b5aedefSNico Weber DependencyOutputOptions &DepOpts, const FrontendOptions &Opts) { 7241b3240b0SArgyrios Kyrtzidis SrcMgr::CharacteristicKind 725873c8583SArgyrios Kyrtzidis Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; 7261b3240b0SArgyrios Kyrtzidis 7276566e23eSArgyrios Kyrtzidis if (Input.isBuffer()) { 72850a5f97eSDavid Blaikie SourceMgr.setMainFileID(SourceMgr.createFileID( 72950a5f97eSDavid Blaikie std::unique_ptr<llvm::MemoryBuffer>(Input.getBuffer()), Kind)); 7308b563665SYaron Keren assert(SourceMgr.getMainFileID().isValid() && 7316566e23eSArgyrios Kyrtzidis "Couldn't establish MainFileID!"); 7326566e23eSArgyrios Kyrtzidis return true; 7336566e23eSArgyrios Kyrtzidis } 7346566e23eSArgyrios Kyrtzidis 7356566e23eSArgyrios Kyrtzidis StringRef InputFile = Input.getFile(); 7366566e23eSArgyrios Kyrtzidis 7377c06d866SArgyrios Kyrtzidis // Figure out where to get and map in the main file. 7387c06d866SArgyrios Kyrtzidis if (InputFile != "-") { 7392ca4be97SNico Weber const FileEntry *File; 7402ca4be97SNico Weber if (Opts.FindPchSource.empty()) { 7412ca4be97SNico Weber File = FileMgr.getFile(InputFile, /*OpenFile=*/true); 7422ca4be97SNico Weber } else { 7432ca4be97SNico Weber // When building a pch file in clang-cl mode, the .h file is built as if 7442ca4be97SNico Weber // it was included by a cc file. Since the driver doesn't know about 7452ca4be97SNico Weber // all include search directories, the frontend must search the input 7462ca4be97SNico Weber // file through HeaderSearch here, as if it had been included by the 7472ca4be97SNico Weber // cc file at Opts.FindPchSource. 7482ca4be97SNico Weber const FileEntry *FindFile = FileMgr.getFile(Opts.FindPchSource); 7492ca4be97SNico Weber if (!FindFile) { 7502ca4be97SNico Weber Diags.Report(diag::err_fe_error_reading) << Opts.FindPchSource; 7512ca4be97SNico Weber return false; 7522ca4be97SNico Weber } 7532ca4be97SNico Weber const DirectoryLookup *UnusedCurDir; 7542ca4be97SNico Weber SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 16> 7552ca4be97SNico Weber Includers; 7562ca4be97SNico Weber Includers.push_back(std::make_pair(FindFile, FindFile->getDir())); 7572ca4be97SNico Weber File = HS->LookupFile(InputFile, SourceLocation(), /*isAngled=*/false, 7582ca4be97SNico Weber /*FromDir=*/nullptr, 7592ca4be97SNico Weber /*CurDir=*/UnusedCurDir, Includers, 7602ca4be97SNico Weber /*SearchPath=*/nullptr, 7612ca4be97SNico Weber /*RelativePath=*/nullptr, 7622ca4be97SNico Weber /*RequestingModule=*/nullptr, 7632ca4be97SNico Weber /*SuggestedModule=*/nullptr, /*SkipCache=*/true); 7644b5aedefSNico Weber // Also add the header to /showIncludes output. 7654b5aedefSNico Weber if (File) 766f54146c1SNico Weber DepOpts.ShowIncludesPretendHeader = File->getName(); 7672ca4be97SNico Weber } 76852765215SDan Gohman if (!File) { 769409e890fSDaniel Dunbar Diags.Report(diag::err_fe_error_reading) << InputFile; 770409e890fSDaniel Dunbar return false; 771409e890fSDaniel Dunbar } 772e2951f48SDaniel Dunbar 773e2951f48SDaniel Dunbar // The natural SourceManager infrastructure can't currently handle named 774e2951f48SDaniel Dunbar // pipes, but we would at least like to accept them for the main 7753841fa38SBenjamin Kramer // file. Detect them here, read them with the volatile flag so FileMgr will 7763841fa38SBenjamin Kramer // pick up the correct size, and simply override their contents as we do for 7773841fa38SBenjamin Kramer // STDIN. 778e2951f48SDaniel Dunbar if (File->isNamedPipe()) { 779a885796dSBenjamin Kramer auto MB = FileMgr.getBufferForFile(File, /*isVolatile=*/true); 780a885796dSBenjamin Kramer if (MB) { 781db0745abSDaniel Dunbar // Create a new virtual file that will have the correct size. 782a885796dSBenjamin Kramer File = FileMgr.getVirtualFile(InputFile, (*MB)->getBufferSize(), 0); 783a885796dSBenjamin Kramer SourceMgr.overrideFileContents(File, std::move(*MB)); 7843841fa38SBenjamin Kramer } else { 785a885796dSBenjamin Kramer Diags.Report(diag::err_cannot_open_file) << InputFile 786a885796dSBenjamin Kramer << MB.getError().message(); 7873841fa38SBenjamin Kramer return false; 7883841fa38SBenjamin Kramer } 789e2951f48SDaniel Dunbar } 790db0745abSDaniel Dunbar 791b671e34cSAlp Toker SourceMgr.setMainFileID( 792b671e34cSAlp Toker SourceMgr.createFileID(File, SourceLocation(), Kind)); 793409e890fSDaniel Dunbar } else { 7942d2b420aSRafael Espindola llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> SBOrErr = 7952d2b420aSRafael Espindola llvm::MemoryBuffer::getSTDIN(); 7962d2b420aSRafael Espindola if (std::error_code EC = SBOrErr.getError()) { 7972d2b420aSRafael Espindola Diags.Report(diag::err_fe_error_reading_stdin) << EC.message(); 798409e890fSDaniel Dunbar return false; 799409e890fSDaniel Dunbar } 8002d2b420aSRafael Espindola std::unique_ptr<llvm::MemoryBuffer> SB = std::move(SBOrErr.get()); 8012d2b420aSRafael Espindola 8022f76cd75SDan Gohman const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), 8035159f616SChris Lattner SB->getBufferSize(), 0); 804b671e34cSAlp Toker SourceMgr.setMainFileID( 805b671e34cSAlp Toker SourceMgr.createFileID(File, SourceLocation(), Kind)); 80649cc3181SDavid Blaikie SourceMgr.overrideFileContents(File, std::move(SB)); 807409e890fSDaniel Dunbar } 808409e890fSDaniel Dunbar 8098b563665SYaron Keren assert(SourceMgr.getMainFileID().isValid() && 81052765215SDan Gohman "Couldn't establish MainFileID!"); 811409e890fSDaniel Dunbar return true; 812409e890fSDaniel Dunbar } 8134f2bc55dSDaniel Dunbar 8144f2bc55dSDaniel Dunbar // High-Level Operations 8154f2bc55dSDaniel Dunbar 8164f2bc55dSDaniel Dunbar bool CompilerInstance::ExecuteAction(FrontendAction &Act) { 8174f2bc55dSDaniel Dunbar assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); 8184f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); 8194f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); 8204f2bc55dSDaniel Dunbar 8214f2bc55dSDaniel Dunbar // FIXME: Take this as an argument, once all the APIs we used have moved to 8224f2bc55dSDaniel Dunbar // taking it as an input instead of hard-coding llvm::errs. 8230e62c1ccSChris Lattner raw_ostream &OS = llvm::errs(); 8244f2bc55dSDaniel Dunbar 8254f2bc55dSDaniel Dunbar // Create the target instance. 82680758084SAlp Toker setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), 82710a4972aSSaleem Abdulrasool getInvocation().TargetOpts)); 8284f2bc55dSDaniel Dunbar if (!hasTarget()) 8294f2bc55dSDaniel Dunbar return false; 8304f2bc55dSDaniel Dunbar 831b5bc923aSArtem Belevich // Create TargetInfo for the other side of CUDA compilation. 832b5bc923aSArtem Belevich if (getLangOpts().CUDA && !getFrontendOpts().AuxTriple.empty()) { 83376945b2fSJustin Lebar auto TO = std::make_shared<TargetOptions>(); 834b5bc923aSArtem Belevich TO->Triple = getFrontendOpts().AuxTriple; 83576945b2fSJustin Lebar TO->HostTriple = getTarget().getTriple().str(); 83610a4972aSSaleem Abdulrasool setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO)); 837b5bc923aSArtem Belevich } 838b5bc923aSArtem Belevich 8394f2bc55dSDaniel Dunbar // Inform the target of the language options. 8404f2bc55dSDaniel Dunbar // 8414f2bc55dSDaniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 8424f2bc55dSDaniel Dunbar // created. This complexity should be lifted elsewhere. 84374437975SAlp Toker getTarget().adjust(getLangOpts()); 8444f2bc55dSDaniel Dunbar 8452c17e82bSYaxun Liu // Adjust target options based on codegen options. 8462c17e82bSYaxun Liu getTarget().adjustTargetOptions(getCodeGenOpts(), getTargetOpts()); 8472c17e82bSYaxun Liu 84829898f45SFariborz Jahanian // rewriter project will change target built-in bool type from its default. 84929898f45SFariborz Jahanian if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) 85029898f45SFariborz Jahanian getTarget().noSignedCharForObjCBool(); 85129898f45SFariborz Jahanian 8524f2bc55dSDaniel Dunbar // Validate/process some options. 8534f2bc55dSDaniel Dunbar if (getHeaderSearchOpts().Verbose) 8544f2bc55dSDaniel Dunbar OS << "clang -cc1 version " CLANG_VERSION_STRING 855f988d006SAlp Toker << " based upon " << BACKEND_PACKAGE_STRING 8568188c8a1SSebastian Pop << " default target " << llvm::sys::getDefaultTargetTriple() << "\n"; 8574f2bc55dSDaniel Dunbar 8584f2bc55dSDaniel Dunbar if (getFrontendOpts().ShowTimers) 8594f2bc55dSDaniel Dunbar createFrontendTimer(); 8604f2bc55dSDaniel Dunbar 861171b780cSDouglas Gregor if (getFrontendOpts().ShowStats) 862171b780cSDouglas Gregor llvm::EnableStatistics(); 863171b780cSDouglas Gregor 8645b60ad68SVedant Kumar for (const FrontendInputFile &FIF : getFrontendOpts().Inputs) { 865eeccb30bSTed Kremenek // Reset the ID tables if we are reusing the SourceManager and parsing 866eeccb30bSTed Kremenek // regular files. 867eeccb30bSTed Kremenek if (hasSourceManager() && !Act.isModelParsingAction()) 8684f2bc55dSDaniel Dunbar getSourceManager().clearIDTables(); 8694f2bc55dSDaniel Dunbar 8705b60ad68SVedant Kumar if (Act.BeginSourceFile(*this, FIF)) { 8714f2bc55dSDaniel Dunbar Act.Execute(); 8724f2bc55dSDaniel Dunbar Act.EndSourceFile(); 8734f2bc55dSDaniel Dunbar } 8744f2bc55dSDaniel Dunbar } 8754f2bc55dSDaniel Dunbar 8767910d7b7SArgyrios Kyrtzidis // Notify the diagnostic client that all files were processed. 8777910d7b7SArgyrios Kyrtzidis getDiagnostics().getClient()->finish(); 8787910d7b7SArgyrios Kyrtzidis 879198cb4dfSChris Lattner if (getDiagnosticOpts().ShowCarets) { 880c79346a5SArgyrios Kyrtzidis // We can have multiple diagnostics sharing one diagnostic client. 881c79346a5SArgyrios Kyrtzidis // Get the total number of warnings/errors from the client. 882c79346a5SArgyrios Kyrtzidis unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); 883c79346a5SArgyrios Kyrtzidis unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); 884198cb4dfSChris Lattner 885198cb4dfSChris Lattner if (NumWarnings) 886198cb4dfSChris Lattner OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); 887198cb4dfSChris Lattner if (NumWarnings && NumErrors) 888198cb4dfSChris Lattner OS << " and "; 889198cb4dfSChris Lattner if (NumErrors) 890198cb4dfSChris Lattner OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); 891198cb4dfSChris Lattner if (NumWarnings || NumErrors) 892198cb4dfSChris Lattner OS << " generated.\n"; 893198cb4dfSChris Lattner } 8944f2bc55dSDaniel Dunbar 895aed46fcbSDaniel Dunbar if (getFrontendOpts().ShowStats && hasFileManager()) { 8964f2bc55dSDaniel Dunbar getFileManager().PrintStats(); 8974f2bc55dSDaniel Dunbar OS << "\n"; 8984f2bc55dSDaniel Dunbar } 8994f2bc55dSDaniel Dunbar 900bc467933SArgyrios Kyrtzidis return !getDiagnostics().getClient()->getNumErrors(); 9014f2bc55dSDaniel Dunbar } 9024f2bc55dSDaniel Dunbar 903faeb1d46SDouglas Gregor /// \brief Determine the appropriate source input kind based on language 904faeb1d46SDouglas Gregor /// options. 905faeb1d46SDouglas Gregor static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) { 906faeb1d46SDouglas Gregor if (LangOpts.OpenCL) 907faeb1d46SDouglas Gregor return IK_OpenCL; 908faeb1d46SDouglas Gregor if (LangOpts.CUDA) 909faeb1d46SDouglas Gregor return IK_CUDA; 910faeb1d46SDouglas Gregor if (LangOpts.ObjC1) 911faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC; 912faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_CXX : IK_C; 913faeb1d46SDouglas Gregor } 914faeb1d46SDouglas Gregor 915514b636aSDouglas Gregor /// \brief Compile a module file for the given module, using the options 916b797d59fSBen Langmuir /// provided by the importing compiler instance. Returns true if the module 917b797d59fSBen Langmuir /// was built without errors. 918b797d59fSBen Langmuir static bool compileModuleImpl(CompilerInstance &ImportingInstance, 919af8f0263SDouglas Gregor SourceLocation ImportLoc, 920de3ef502SDouglas Gregor Module *Module, 9216dc57927SDouglas Gregor StringRef ModuleFileName) { 922514b636aSDouglas Gregor ModuleMap &ModMap 923514b636aSDouglas Gregor = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); 924514b636aSDouglas Gregor 925faeb1d46SDouglas Gregor // Construct a compiler invocation for creating this module. 926c95d8192SDylan Noblesmith IntrusiveRefCntPtr<CompilerInvocation> Invocation 927faeb1d46SDouglas Gregor (new CompilerInvocation(ImportingInstance.getInvocation())); 92844bf68d8SDouglas Gregor 929f545f67dSDouglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 930f545f67dSDouglas Gregor 93144bf68d8SDouglas Gregor // For any options that aren't intended to affect how a module is built, 93244bf68d8SDouglas Gregor // reset them to their default values. 9338cf47df7STed Kremenek Invocation->getLangOpts()->resetNonModularOptions(); 934f545f67dSDouglas Gregor PPOpts.resetNonModularOptions(); 93544bf68d8SDouglas Gregor 9365dc3899cSDouglas Gregor // Remove any macro definitions that are explicitly ignored by the module. 9375dc3899cSDouglas Gregor // They aren't supposed to affect how the module is built anyway. 9385dc3899cSDouglas Gregor const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); 939bbdd7640SBenjamin Kramer PPOpts.Macros.erase( 940bbdd7640SBenjamin Kramer std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), 941bbdd7640SBenjamin Kramer [&HSOpts](const std::pair<std::string, bool> &def) { 942bbdd7640SBenjamin Kramer StringRef MacroDef = def.first; 943bbdd7640SBenjamin Kramer return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0; 944bbdd7640SBenjamin Kramer }), 9455dc3899cSDouglas Gregor PPOpts.Macros.end()); 9465dc3899cSDouglas Gregor 9477d106e42SDouglas Gregor // Note the name of the module we're building. 9486dc57927SDouglas Gregor Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName(); 9497d106e42SDouglas Gregor 9507a626570SDouglas Gregor // Make sure that the failed-module structure has been allocated in 9517a626570SDouglas Gregor // the importing instance, and propagate the pointer to the newly-created 9527a626570SDouglas Gregor // instance. 9537a626570SDouglas Gregor PreprocessorOptions &ImportingPPOpts 9547a626570SDouglas Gregor = ImportingInstance.getInvocation().getPreprocessorOpts(); 9557a626570SDouglas Gregor if (!ImportingPPOpts.FailedModules) 9567a626570SDouglas Gregor ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet; 9577a626570SDouglas Gregor PPOpts.FailedModules = ImportingPPOpts.FailedModules; 9587a626570SDouglas Gregor 959514b636aSDouglas Gregor // If there is a module map file, build the module using the module map. 960514b636aSDouglas Gregor // Set up the inputs/outputs so that we build the module from its umbrella 961514b636aSDouglas Gregor // header. 962514b636aSDouglas Gregor FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); 963514b636aSDouglas Gregor FrontendOpts.OutputFile = ModuleFileName.str(); 964514b636aSDouglas Gregor FrontendOpts.DisableFree = false; 965c1bbec85SDouglas Gregor FrontendOpts.GenerateGlobalModuleIndex = false; 966e75ee0f0SRichard Smith FrontendOpts.BuildingImplicitModule = true; 967514b636aSDouglas Gregor FrontendOpts.Inputs.clear(); 968f545f67dSDouglas Gregor InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts()); 969f545f67dSDouglas Gregor 970f545f67dSDouglas Gregor // Don't free the remapped file buffers; they are owned by our caller. 971f545f67dSDouglas Gregor PPOpts.RetainRemappedFileBuffers = true; 972514b636aSDouglas Gregor 973514b636aSDouglas Gregor Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; 974514b636aSDouglas Gregor assert(ImportingInstance.getInvocation().getModuleHash() == 975514b636aSDouglas Gregor Invocation->getModuleHash() && "Module hash mismatch!"); 976514b636aSDouglas Gregor 977514b636aSDouglas Gregor // Construct a compiler instance that will be used to actually create the 978514b636aSDouglas Gregor // module. 979bb165fb0SAdrian Prantl CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(), 980bb165fb0SAdrian Prantl /*BuildingModule=*/true); 981514b636aSDouglas Gregor Instance.setInvocation(&*Invocation); 9826b930967SDouglas Gregor 9836b930967SDouglas Gregor Instance.createDiagnostics(new ForwardingDiagnosticConsumer( 9846b930967SDouglas Gregor ImportingInstance.getDiagnosticClient()), 98530071ceaSDouglas Gregor /*ShouldOwnClient=*/true); 986514b636aSDouglas Gregor 987c8130a74SBen Langmuir Instance.setVirtualFileSystem(&ImportingInstance.getVirtualFileSystem()); 988c8130a74SBen Langmuir 98963365431SDouglas Gregor // Note that this module is part of the module build stack, so that we 990af8f0263SDouglas Gregor // can detect cycles in the module graph. 991d066d4c8SBen Langmuir Instance.setFileManager(&ImportingInstance.getFileManager()); 992af8f0263SDouglas Gregor Instance.createSourceManager(Instance.getFileManager()); 993af8f0263SDouglas Gregor SourceManager &SourceMgr = Instance.getSourceManager(); 99463365431SDouglas Gregor SourceMgr.setModuleBuildStack( 99563365431SDouglas Gregor ImportingInstance.getSourceManager().getModuleBuildStack()); 99663365431SDouglas Gregor SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(), 997af8f0263SDouglas Gregor FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); 998af8f0263SDouglas Gregor 99986d1259cSJustin Bogner // If we're collecting module dependencies, we need to share a collector 100038c1e6d3SRichard Smith // between all of the module CompilerInstances. Other than that, we don't 100138c1e6d3SRichard Smith // want to produce any dependency output from the module build. 100286d1259cSJustin Bogner Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector()); 100338c1e6d3SRichard Smith Invocation->getDependencyOutputOpts() = DependencyOutputOptions(); 100486d1259cSJustin Bogner 10051f76c4e8SManuel Klimek // Get or create the module map that we'll use to build this module. 10061f76c4e8SManuel Klimek std::string InferredModuleMapContent; 10071f76c4e8SManuel Klimek if (const FileEntry *ModuleMapFile = 10081f76c4e8SManuel Klimek ModMap.getContainingModuleMapFile(Module)) { 10091f76c4e8SManuel Klimek // Use the module map where this module resides. 10103204b152SBenjamin Kramer FrontendOpts.Inputs.emplace_back(ModuleMapFile->getName(), IK); 10111f76c4e8SManuel Klimek } else { 10122b63d15fSRichard Smith SmallString<128> FakeModuleMapFile(Module->Directory->getName()); 10132b63d15fSRichard Smith llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map"); 10143204b152SBenjamin Kramer FrontendOpts.Inputs.emplace_back(FakeModuleMapFile, IK); 10152b63d15fSRichard Smith 10161f76c4e8SManuel Klimek llvm::raw_string_ostream OS(InferredModuleMapContent); 10171f76c4e8SManuel Klimek Module->print(OS); 10181f76c4e8SManuel Klimek OS.flush(); 10191f76c4e8SManuel Klimek 1020d87f8d76SRafael Espindola std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = 10211f76c4e8SManuel Klimek llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent); 10221f76c4e8SManuel Klimek ModuleMapFile = Instance.getFileManager().getVirtualFile( 10232b63d15fSRichard Smith FakeModuleMapFile, InferredModuleMapContent.size(), 0); 102449cc3181SDavid Blaikie SourceMgr.overrideFileContents(ModuleMapFile, std::move(ModuleMapBuffer)); 10251f76c4e8SManuel Klimek } 1026af8f0263SDouglas Gregor 10279d6448b1SBen Langmuir // Construct a module-generating action. Passing through the module map is 1028beee15e7SBen Langmuir // safe because the FileManager is shared between the compiler instances. 1029*bbcc9f04SRichard Smith GenerateModuleFromModuleMapAction CreateModuleAction( 10309d6448b1SBen Langmuir ModMap.getModuleMapFileForUniquing(Module), Module->IsSystem); 1031514b636aSDouglas Gregor 103299891da7SRichard Smith ImportingInstance.getDiagnostics().Report(ImportLoc, 103399891da7SRichard Smith diag::remark_module_build) 103499891da7SRichard Smith << Module->Name << ModuleFileName; 103599891da7SRichard Smith 1036514b636aSDouglas Gregor // Execute the action to actually build the module in-place. Use a separate 1037514b636aSDouglas Gregor // thread so that we get a stack large enough. 1038514b636aSDouglas Gregor const unsigned ThreadStackSize = 8 << 20; 1039514b636aSDouglas Gregor llvm::CrashRecoveryContext CRC; 1040841f1c78SRichard Smith CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(CreateModuleAction); }, 1041841f1c78SRichard Smith ThreadStackSize); 10426b930967SDouglas Gregor 104399891da7SRichard Smith ImportingInstance.getDiagnostics().Report(ImportLoc, 104499891da7SRichard Smith diag::remark_module_build_done) 104599891da7SRichard Smith << Module->Name; 104699891da7SRichard Smith 1047f545f67dSDouglas Gregor // Delete the temporary module map file. 1048f545f67dSDouglas Gregor // FIXME: Even though we're executing under crash protection, it would still 1049f545f67dSDouglas Gregor // be nice to do this with RemoveFileOnSignal when we can. However, that 1050f545f67dSDouglas Gregor // doesn't make sense for all clients, so clean this up manually. 105113afbf42SBenjamin Kramer Instance.clearOutputFiles(/*EraseFiles=*/true); 10525e306b12SDouglas Gregor 10535e306b12SDouglas Gregor // We've rebuilt a module. If we're allowed to generate or update the global 10545e306b12SDouglas Gregor // module index, record that fact in the importing compiler instance. 1055c1bbec85SDouglas Gregor if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) { 10565e306b12SDouglas Gregor ImportingInstance.setBuildGlobalModuleIndex(true); 10575e306b12SDouglas Gregor } 1058b797d59fSBen Langmuir 1059b797d59fSBen Langmuir return !Instance.getDiagnostics().hasErrorOccurred(); 1060faeb1d46SDouglas Gregor } 1061faeb1d46SDouglas Gregor 1062dbdc0368SBen Langmuir static bool compileAndLoadModule(CompilerInstance &ImportingInstance, 10634382fe74SArgyrios Kyrtzidis SourceLocation ImportLoc, 1064b797d59fSBen Langmuir SourceLocation ModuleNameLoc, Module *Module, 10654382fe74SArgyrios Kyrtzidis StringRef ModuleFileName) { 1066d213aab7SBen Langmuir DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); 1067d213aab7SBen Langmuir 1068b797d59fSBen Langmuir auto diagnoseBuildFailure = [&] { 1069d213aab7SBen Langmuir Diags.Report(ModuleNameLoc, diag::err_module_not_built) 1070b797d59fSBen Langmuir << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); 1071b797d59fSBen Langmuir }; 1072b797d59fSBen Langmuir 10734382fe74SArgyrios Kyrtzidis // FIXME: have LockFileManager return an error_code so that we can 10744382fe74SArgyrios Kyrtzidis // avoid the mkdir when the directory already exists. 10754382fe74SArgyrios Kyrtzidis StringRef Dir = llvm::sys::path::parent_path(ModuleFileName); 10764382fe74SArgyrios Kyrtzidis llvm::sys::fs::create_directories(Dir); 10774382fe74SArgyrios Kyrtzidis 10784382fe74SArgyrios Kyrtzidis while (1) { 1079dbdc0368SBen Langmuir unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing; 10804382fe74SArgyrios Kyrtzidis llvm::LockFileManager Locked(ModuleFileName); 10814382fe74SArgyrios Kyrtzidis switch (Locked) { 10824382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Error: 1083d213aab7SBen Langmuir Diags.Report(ModuleNameLoc, diag::err_module_lock_failure) 10844a52222cSBruno Cardoso Lopes << Module->Name << Locked.getErrorMessage(); 1085dbdc0368SBen Langmuir return false; 10864382fe74SArgyrios Kyrtzidis 10874382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Owned: 1088dbdc0368SBen Langmuir // We're responsible for building the module ourselves. 1089b797d59fSBen Langmuir if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module, 1090b797d59fSBen Langmuir ModuleFileName)) { 1091b797d59fSBen Langmuir diagnoseBuildFailure(); 1092b797d59fSBen Langmuir return false; 1093b797d59fSBen Langmuir } 10944382fe74SArgyrios Kyrtzidis break; 10954382fe74SArgyrios Kyrtzidis 10964382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Shared: 10974382fe74SArgyrios Kyrtzidis // Someone else is responsible for building the module. Wait for them to 10984382fe74SArgyrios Kyrtzidis // finish. 10991daf4801SBen Langmuir switch (Locked.waitForUnlock()) { 11001daf4801SBen Langmuir case llvm::LockFileManager::Res_Success: 1101dbdc0368SBen Langmuir ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate; 1102dbdc0368SBen Langmuir break; 11031daf4801SBen Langmuir case llvm::LockFileManager::Res_OwnerDied: 11041daf4801SBen Langmuir continue; // try again to get the lock. 11051daf4801SBen Langmuir case llvm::LockFileManager::Res_Timeout: 11061daf4801SBen Langmuir Diags.Report(ModuleNameLoc, diag::err_module_lock_timeout) 11071daf4801SBen Langmuir << Module->Name; 11081daf4801SBen Langmuir // Clear the lock file so that future invokations can make progress. 11091daf4801SBen Langmuir Locked.unsafeRemoveLockFile(); 11101daf4801SBen Langmuir return false; 11111daf4801SBen Langmuir } 11121daf4801SBen Langmuir break; 11134382fe74SArgyrios Kyrtzidis } 11144382fe74SArgyrios Kyrtzidis 1115dbdc0368SBen Langmuir // Try to read the module file, now that we've compiled it. 1116dbdc0368SBen Langmuir ASTReader::ASTReadResult ReadResult = 1117dbdc0368SBen Langmuir ImportingInstance.getModuleManager()->ReadAST( 1118e842a474SRichard Smith ModuleFileName, serialization::MK_ImplicitModule, ImportLoc, 1119dbdc0368SBen Langmuir ModuleLoadCapabilities); 1120dbdc0368SBen Langmuir 1121dbdc0368SBen Langmuir if (ReadResult == ASTReader::OutOfDate && 1122dbdc0368SBen Langmuir Locked == llvm::LockFileManager::LFS_Shared) { 1123dbdc0368SBen Langmuir // The module may be out of date in the presence of file system races, 1124dbdc0368SBen Langmuir // or if one of its imports depends on header search paths that are not 1125dbdc0368SBen Langmuir // consistent with this ImportingInstance. Try again... 1126dbdc0368SBen Langmuir continue; 1127dbdc0368SBen Langmuir } else if (ReadResult == ASTReader::Missing) { 1128b797d59fSBen Langmuir diagnoseBuildFailure(); 1129d213aab7SBen Langmuir } else if (ReadResult != ASTReader::Success && 1130d213aab7SBen Langmuir !Diags.hasErrorOccurred()) { 1131d213aab7SBen Langmuir // The ASTReader didn't diagnose the error, so conservatively report it. 1132d213aab7SBen Langmuir diagnoseBuildFailure(); 1133dbdc0368SBen Langmuir } 1134dbdc0368SBen Langmuir return ReadResult == ASTReader::Success; 11354382fe74SArgyrios Kyrtzidis } 11364382fe74SArgyrios Kyrtzidis } 11374382fe74SArgyrios Kyrtzidis 113835b13eceSDouglas Gregor /// \brief Diagnose differences between the current definition of the given 113935b13eceSDouglas Gregor /// configuration macro and the definition provided on the command line. 114035b13eceSDouglas Gregor static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, 114135b13eceSDouglas Gregor Module *Mod, SourceLocation ImportLoc) { 114235b13eceSDouglas Gregor IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro); 114335b13eceSDouglas Gregor SourceManager &SourceMgr = PP.getSourceManager(); 114435b13eceSDouglas Gregor 114535b13eceSDouglas Gregor // If this identifier has never had a macro definition, then it could 114635b13eceSDouglas Gregor // not have changed. 114735b13eceSDouglas Gregor if (!Id->hadMacroDefinition()) 114835b13eceSDouglas Gregor return; 114920e883e5SRichard Smith auto *LatestLocalMD = PP.getLocalMacroDirectiveHistory(Id); 115035b13eceSDouglas Gregor 115120e883e5SRichard Smith // Find the macro definition from the command line. 115220e883e5SRichard Smith MacroInfo *CmdLineDefinition = nullptr; 115320e883e5SRichard Smith for (auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) { 115435b13eceSDouglas Gregor // We only care about the predefines buffer. 115520e883e5SRichard Smith FileID FID = SourceMgr.getFileID(MD->getLocation()); 115620e883e5SRichard Smith if (FID.isInvalid() || FID != PP.getPredefinesFileID()) 115735b13eceSDouglas Gregor continue; 115820e883e5SRichard Smith if (auto *DMD = dyn_cast<DefMacroDirective>(MD)) 115920e883e5SRichard Smith CmdLineDefinition = DMD->getMacroInfo(); 116020e883e5SRichard Smith break; 116120e883e5SRichard Smith } 116235b13eceSDouglas Gregor 116320e883e5SRichard Smith auto *CurrentDefinition = PP.getMacroInfo(Id); 116420e883e5SRichard Smith if (CurrentDefinition == CmdLineDefinition) { 116520e883e5SRichard Smith // Macro matches. Nothing to do. 116620e883e5SRichard Smith } else if (!CurrentDefinition) { 116735b13eceSDouglas Gregor // This macro was defined on the command line, then #undef'd later. 116835b13eceSDouglas Gregor // Complain. 116935b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 117035b13eceSDouglas Gregor << true << ConfigMacro << Mod->getFullModuleName(); 117120e883e5SRichard Smith auto LatestDef = LatestLocalMD->getDefinition(); 117220e883e5SRichard Smith assert(LatestDef.isUndefined() && 117320e883e5SRichard Smith "predefined macro went away with no #undef?"); 1174b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here) 117535b13eceSDouglas Gregor << true; 117635b13eceSDouglas Gregor return; 117720e883e5SRichard Smith } else if (!CmdLineDefinition) { 117820e883e5SRichard Smith // There was no definition for this macro in the predefines buffer, 117920e883e5SRichard Smith // but there was a local definition. Complain. 118035b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 118135b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 118220e883e5SRichard Smith PP.Diag(CurrentDefinition->getDefinitionLoc(), 118320e883e5SRichard Smith diag::note_module_def_undef_here) 118435b13eceSDouglas Gregor << false; 118520e883e5SRichard Smith } else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP, 118620e883e5SRichard Smith /*Syntactically=*/true)) { 118735b13eceSDouglas Gregor // The macro definitions differ. 118835b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 118935b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 119020e883e5SRichard Smith PP.Diag(CurrentDefinition->getDefinitionLoc(), 119120e883e5SRichard Smith diag::note_module_def_undef_here) 119235b13eceSDouglas Gregor << false; 119335b13eceSDouglas Gregor } 119420e883e5SRichard Smith } 119535b13eceSDouglas Gregor 1196527b1c95SDouglas Gregor /// \brief Write a new timestamp file with the given path. 1197527b1c95SDouglas Gregor static void writeTimestampFile(StringRef TimestampFile) { 1198dae941a6SRafael Espindola std::error_code EC; 1199dae941a6SRafael Espindola llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None); 1200527b1c95SDouglas Gregor } 1201527b1c95SDouglas Gregor 1202527b1c95SDouglas Gregor /// \brief Prune the module cache of modules that haven't been accessed in 1203527b1c95SDouglas Gregor /// a long time. 1204527b1c95SDouglas Gregor static void pruneModuleCache(const HeaderSearchOptions &HSOpts) { 1205527b1c95SDouglas Gregor struct stat StatBuf; 1206527b1c95SDouglas Gregor llvm::SmallString<128> TimestampFile; 1207527b1c95SDouglas Gregor TimestampFile = HSOpts.ModuleCachePath; 12083938f0c7SRichard Smith assert(!TimestampFile.empty()); 1209527b1c95SDouglas Gregor llvm::sys::path::append(TimestampFile, "modules.timestamp"); 1210527b1c95SDouglas Gregor 1211527b1c95SDouglas Gregor // Try to stat() the timestamp file. 1212527b1c95SDouglas Gregor if (::stat(TimestampFile.c_str(), &StatBuf)) { 1213527b1c95SDouglas Gregor // If the timestamp file wasn't there, create one now. 1214527b1c95SDouglas Gregor if (errno == ENOENT) { 1215527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1216527b1c95SDouglas Gregor } 1217527b1c95SDouglas Gregor return; 1218527b1c95SDouglas Gregor } 1219527b1c95SDouglas Gregor 1220527b1c95SDouglas Gregor // Check whether the time stamp is older than our pruning interval. 1221527b1c95SDouglas Gregor // If not, do nothing. 1222527b1c95SDouglas Gregor time_t TimeStampModTime = StatBuf.st_mtime; 122349a2790fSCraig Topper time_t CurrentTime = time(nullptr); 1224dbcf5037SBenjamin Kramer if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval)) 1225527b1c95SDouglas Gregor return; 1226527b1c95SDouglas Gregor 1227527b1c95SDouglas Gregor // Write a new timestamp file so that nobody else attempts to prune. 1228527b1c95SDouglas Gregor // There is a benign race condition here, if two Clang instances happen to 1229527b1c95SDouglas Gregor // notice at the same time that the timestamp is out-of-date. 1230527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1231527b1c95SDouglas Gregor 1232527b1c95SDouglas Gregor // Walk the entire module cache, looking for unused module files and module 1233527b1c95SDouglas Gregor // indices. 1234c080917eSRafael Espindola std::error_code EC; 1235527b1c95SDouglas Gregor SmallString<128> ModuleCachePathNative; 1236527b1c95SDouglas Gregor llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative); 123792e1b62dSYaron Keren for (llvm::sys::fs::directory_iterator Dir(ModuleCachePathNative, EC), DirEnd; 1238527b1c95SDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 1239527b1c95SDouglas Gregor // If we don't have a directory, there's nothing to look into. 1240a07f720aSRafael Espindola if (!llvm::sys::fs::is_directory(Dir->path())) 1241527b1c95SDouglas Gregor continue; 1242527b1c95SDouglas Gregor 1243527b1c95SDouglas Gregor // Walk all of the files within this directory. 1244527b1c95SDouglas Gregor for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd; 1245527b1c95SDouglas Gregor File != FileEnd && !EC; File.increment(EC)) { 1246527b1c95SDouglas Gregor // We only care about module and global module index files. 1247f430da4dSDmitri Gribenko StringRef Extension = llvm::sys::path::extension(File->path()); 1248f430da4dSDmitri Gribenko if (Extension != ".pcm" && Extension != ".timestamp" && 1249f430da4dSDmitri Gribenko llvm::sys::path::filename(File->path()) != "modules.idx") 1250527b1c95SDouglas Gregor continue; 1251527b1c95SDouglas Gregor 1252527b1c95SDouglas Gregor // Look at this file. If we can't stat it, there's nothing interesting 1253527b1c95SDouglas Gregor // there. 1254f430da4dSDmitri Gribenko if (::stat(File->path().c_str(), &StatBuf)) 1255527b1c95SDouglas Gregor continue; 1256527b1c95SDouglas Gregor 1257527b1c95SDouglas Gregor // If the file has been used recently enough, leave it there. 1258527b1c95SDouglas Gregor time_t FileAccessTime = StatBuf.st_atime; 1259dbcf5037SBenjamin Kramer if (CurrentTime - FileAccessTime <= 1260dbcf5037SBenjamin Kramer time_t(HSOpts.ModuleCachePruneAfter)) { 1261527b1c95SDouglas Gregor continue; 1262527b1c95SDouglas Gregor } 1263527b1c95SDouglas Gregor 1264527b1c95SDouglas Gregor // Remove the file. 1265f430da4dSDmitri Gribenko llvm::sys::fs::remove(File->path()); 1266f430da4dSDmitri Gribenko 1267f430da4dSDmitri Gribenko // Remove the timestamp file. 1268f430da4dSDmitri Gribenko std::string TimpestampFilename = File->path() + ".timestamp"; 1269f430da4dSDmitri Gribenko llvm::sys::fs::remove(TimpestampFilename); 1270527b1c95SDouglas Gregor } 1271527b1c95SDouglas Gregor 1272527b1c95SDouglas Gregor // If we removed all of the files in the directory, remove the directory 1273527b1c95SDouglas Gregor // itself. 1274f430da4dSDmitri Gribenko if (llvm::sys::fs::directory_iterator(Dir->path(), EC) == 1275f430da4dSDmitri Gribenko llvm::sys::fs::directory_iterator() && !EC) 12762a008784SRafael Espindola llvm::sys::fs::remove(Dir->path()); 1277527b1c95SDouglas Gregor } 1278527b1c95SDouglas Gregor } 1279527b1c95SDouglas Gregor 12802255f2ceSJohn Thompson void CompilerInstance::createModuleManager() { 12812255f2ceSJohn Thompson if (!ModuleManager) { 12822255f2ceSJohn Thompson if (!hasASTContext()) 12832255f2ceSJohn Thompson createASTContext(); 12842255f2ceSJohn Thompson 1285580dd296SChandler Carruth // If we're implicitly building modules but not currently recursively 1286580dd296SChandler Carruth // building a module, check whether we need to prune the module cache. 12873938f0c7SRichard Smith if (getSourceManager().getModuleBuildStack().empty() && 12883938f0c7SRichard Smith !getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() && 12892255f2ceSJohn Thompson getHeaderSearchOpts().ModuleCachePruneInterval > 0 && 12902255f2ceSJohn Thompson getHeaderSearchOpts().ModuleCachePruneAfter > 0) { 12912255f2ceSJohn Thompson pruneModuleCache(getHeaderSearchOpts()); 12922255f2ceSJohn Thompson } 12932255f2ceSJohn Thompson 12942255f2ceSJohn Thompson HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); 12952255f2ceSJohn Thompson std::string Sysroot = HSOpts.Sysroot; 12962255f2ceSJohn Thompson const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 1297ce18a187SRichard Smith std::unique_ptr<llvm::Timer> ReadTimer; 1298ce18a187SRichard Smith if (FrontendTimerGroup) 1299ce18a187SRichard Smith ReadTimer = llvm::make_unique<llvm::Timer>("Reading modules", 1300ce18a187SRichard Smith *FrontendTimerGroup); 1301bb165fb0SAdrian Prantl ModuleManager = new ASTReader( 1302293534b1SRichard Smith getPreprocessor(), getASTContext(), getPCHContainerReader(), 13036623e1f1SDouglas Gregor getFrontendOpts().ModuleFileExtensions, 1304bb165fb0SAdrian Prantl Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation, 13052255f2ceSJohn Thompson /*AllowASTWithCompilerErrors=*/false, 13062255f2ceSJohn Thompson /*AllowConfigurationMismatch=*/false, 13072255f2ceSJohn Thompson HSOpts.ModulesValidateSystemHeaders, 1308ce18a187SRichard Smith getFrontendOpts().UseGlobalModuleIndex, 1309ce18a187SRichard Smith std::move(ReadTimer)); 13102255f2ceSJohn Thompson if (hasASTConsumer()) { 13112255f2ceSJohn Thompson ModuleManager->setDeserializationListener( 13122255f2ceSJohn Thompson getASTConsumer().GetASTDeserializationListener()); 13132255f2ceSJohn Thompson getASTContext().setASTMutationListener( 13142255f2ceSJohn Thompson getASTConsumer().GetASTMutationListener()); 13152255f2ceSJohn Thompson } 13162255f2ceSJohn Thompson getASTContext().setExternalSource(ModuleManager); 13172255f2ceSJohn Thompson if (hasSema()) 13182255f2ceSJohn Thompson ModuleManager->InitializeSema(getSema()); 1319293534b1SRichard Smith if (hasASTConsumer()) 13202255f2ceSJohn Thompson ModuleManager->StartTranslationUnit(&getASTConsumer()); 132103f7e611SRichard Smith 132203f7e611SRichard Smith if (TheDependencyFileGenerator) 132303f7e611SRichard Smith TheDependencyFileGenerator->AttachToASTReader(*ModuleManager); 132403f7e611SRichard Smith for (auto &Listener : DependencyCollectors) 132503f7e611SRichard Smith Listener->attachToASTReader(*ModuleManager); 13262255f2ceSJohn Thompson } 13272255f2ceSJohn Thompson } 13282255f2ceSJohn Thompson 1329d4b230b3SRichard Smith bool CompilerInstance::loadModuleFile(StringRef FileName) { 1330ce18a187SRichard Smith llvm::Timer Timer; 1331ce18a187SRichard Smith if (FrontendTimerGroup) 1332ce18a187SRichard Smith Timer.init("Preloading " + FileName.str(), *FrontendTimerGroup); 1333ce18a187SRichard Smith llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); 1334ce18a187SRichard Smith 1335d4b230b3SRichard Smith // Helper to recursively read the module names for all modules we're adding. 1336d4b230b3SRichard Smith // We mark these as known and redirect any attempt to load that module to 1337d4b230b3SRichard Smith // the files we were handed. 1338d4b230b3SRichard Smith struct ReadModuleNames : ASTReaderListener { 1339d4b230b3SRichard Smith CompilerInstance &CI; 13400f99d6a4SRichard Smith llvm::SmallVector<IdentifierInfo*, 8> LoadedModules; 1341e842a474SRichard Smith 13420f99d6a4SRichard Smith ReadModuleNames(CompilerInstance &CI) : CI(CI) {} 1343d4b230b3SRichard Smith 1344d4b230b3SRichard Smith void ReadModuleName(StringRef ModuleName) override { 13450f99d6a4SRichard Smith LoadedModules.push_back( 13460f99d6a4SRichard Smith CI.getPreprocessor().getIdentifierInfo(ModuleName)); 1347d4b230b3SRichard Smith } 13480f99d6a4SRichard Smith 13490f99d6a4SRichard Smith void registerAll() { 13500f99d6a4SRichard Smith for (auto *II : LoadedModules) { 13510f99d6a4SRichard Smith CI.KnownModules[II] = CI.getPreprocessor() 13520f99d6a4SRichard Smith .getHeaderSearchInfo() 13530f99d6a4SRichard Smith .getModuleMap() 13540f99d6a4SRichard Smith .findModule(II->getName()); 13550f99d6a4SRichard Smith } 13560f99d6a4SRichard Smith LoadedModules.clear(); 13570f99d6a4SRichard Smith } 13588a308ec2SRichard Smith 13598a308ec2SRichard Smith void markAllUnavailable() { 13608a308ec2SRichard Smith for (auto *II : LoadedModules) { 13618a308ec2SRichard Smith if (Module *M = CI.getPreprocessor() 13628a308ec2SRichard Smith .getHeaderSearchInfo() 13638a308ec2SRichard Smith .getModuleMap() 13648a308ec2SRichard Smith .findModule(II->getName())) 13658a308ec2SRichard Smith M->HasIncompatibleModuleFile = true; 13668a308ec2SRichard Smith } 13678a308ec2SRichard Smith LoadedModules.clear(); 13688a308ec2SRichard Smith } 13690f99d6a4SRichard Smith }; 1370d4b230b3SRichard Smith 13717f330cdbSRichard Smith // If we don't already have an ASTReader, create one now. 13727f330cdbSRichard Smith if (!ModuleManager) 13737f330cdbSRichard Smith createModuleManager(); 13747f330cdbSRichard Smith 13750f99d6a4SRichard Smith auto Listener = llvm::make_unique<ReadModuleNames>(*this); 13760f99d6a4SRichard Smith auto &ListenerRef = *Listener; 13770f99d6a4SRichard Smith ASTReader::ListenerScope ReadModuleNamesListener(*ModuleManager, 13780f99d6a4SRichard Smith std::move(Listener)); 13797f330cdbSRichard Smith 13800f99d6a4SRichard Smith // Try to load the module file. 138195dc57a6SRichard Smith switch (ModuleManager->ReadAST(FileName, serialization::MK_ExplicitModule, 138295dc57a6SRichard Smith SourceLocation(), 138395dc57a6SRichard Smith ASTReader::ARR_ConfigurationMismatch)) { 138495dc57a6SRichard Smith case ASTReader::Success: 13850f99d6a4SRichard Smith // We successfully loaded the module file; remember the set of provided 13860f99d6a4SRichard Smith // modules so that we don't try to load implicit modules for them. 13870f99d6a4SRichard Smith ListenerRef.registerAll(); 1388d4b230b3SRichard Smith return true; 138995dc57a6SRichard Smith 139095dc57a6SRichard Smith case ASTReader::ConfigurationMismatch: 139195dc57a6SRichard Smith // Ignore unusable module files. 139295dc57a6SRichard Smith getDiagnostics().Report(SourceLocation(), diag::warn_module_config_mismatch) 139395dc57a6SRichard Smith << FileName; 13948a308ec2SRichard Smith // All modules provided by any files we tried and failed to load are now 13958a308ec2SRichard Smith // unavailable; includes of those modules should now be handled textually. 13968a308ec2SRichard Smith ListenerRef.markAllUnavailable(); 139795dc57a6SRichard Smith return true; 139895dc57a6SRichard Smith 139995dc57a6SRichard Smith default: 140095dc57a6SRichard Smith return false; 140195dc57a6SRichard Smith } 1402e842a474SRichard Smith } 1403e842a474SRichard Smith 1404e842a474SRichard Smith ModuleLoadResult 14057a626570SDouglas Gregor CompilerInstance::loadModule(SourceLocation ImportLoc, 1406ff2be53fSDouglas Gregor ModuleIdPath Path, 1407bcfc7d02SDouglas Gregor Module::NameVisibilityKind Visibility, 1408bcfc7d02SDouglas Gregor bool IsInclusionDirective) { 140992304e00SRichard Smith // Determine what file we're searching from. 141092304e00SRichard Smith StringRef ModuleName = Path[0].first->getName(); 141192304e00SRichard Smith SourceLocation ModuleNameLoc = Path[0].second; 141292304e00SRichard Smith 14131805b8a4SDouglas Gregor // If we've already handled this import, just return the cached result. 14141805b8a4SDouglas Gregor // This one-element cache is important to eliminate redundant diagnostics 14151805b8a4SDouglas Gregor // when both the preprocessor and parser see the same import declaration. 14168b563665SYaron Keren if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) { 1417ff2be53fSDouglas Gregor // Make the named module visible. 14187e82e019SRichard Smith if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule) 1419125df058SArgyrios Kyrtzidis ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, 1420a7e2cc68SRichard Smith ImportLoc); 142169021974SDouglas Gregor return LastModuleImportResult; 1422ff2be53fSDouglas Gregor } 14231805b8a4SDouglas Gregor 142449a2790fSCraig Topper clang::Module *Module = nullptr; 14255196bc6bSDouglas Gregor 14265196bc6bSDouglas Gregor // If we don't already have information on this module, load the module now. 1427de3ef502SDouglas Gregor llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known 142869021974SDouglas Gregor = KnownModules.find(Path[0].first); 14292537a364SDouglas Gregor if (Known != KnownModules.end()) { 14302537a364SDouglas Gregor // Retrieve the cached top-level module. 14312537a364SDouglas Gregor Module = Known->second; 14327e82e019SRichard Smith } else if (ModuleName == getLangOpts().CurrentModule) { 14332537a364SDouglas Gregor // This is the module we're building. 1434527040e0SBen Langmuir Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 14352537a364SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 14362537a364SDouglas Gregor } else { 14375196bc6bSDouglas Gregor // Search for a module with the given name. 1438279a6c37SDouglas Gregor Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 143911f2a477SManman Ren HeaderSearchOptions &HSOpts = 144011f2a477SManman Ren PP->getHeaderSearchInfo().getHeaderSearchOpts(); 144111f2a477SManman Ren 144211f2a477SManman Ren std::string ModuleFileName; 144311f2a477SManman Ren bool LoadFromPrebuiltModulePath = false; 144411f2a477SManman Ren // We try to load the module from the prebuilt module paths. If not 144511f2a477SManman Ren // successful, we then try to find it in the module cache. 144611f2a477SManman Ren if (!HSOpts.PrebuiltModulePaths.empty()) { 144711f2a477SManman Ren // Load the module from the prebuilt module path. 144811f2a477SManman Ren ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName( 144911f2a477SManman Ren ModuleName, "", /*UsePrebuiltPath*/ true); 145011f2a477SManman Ren if (!ModuleFileName.empty()) 145111f2a477SManman Ren LoadFromPrebuiltModulePath = true; 145211f2a477SManman Ren } 145311f2a477SManman Ren if (!LoadFromPrebuiltModulePath && Module) { 145411f2a477SManman Ren // Load the module from the module cache. 145511f2a477SManman Ren ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); 145611f2a477SManman Ren } else if (!LoadFromPrebuiltModulePath) { 145711f2a477SManman Ren // We can't find a module, error out here. 14589eb229bfSBen Langmuir getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) 14599eb229bfSBen Langmuir << ModuleName 14609eb229bfSBen Langmuir << SourceRange(ImportLoc, ModuleNameLoc); 14619eb229bfSBen Langmuir ModuleBuildFailed = true; 14629eb229bfSBen Langmuir return ModuleLoadResult(); 14639eb229bfSBen Langmuir } 14649eb229bfSBen Langmuir 1465d520a250SRichard Smith if (ModuleFileName.empty()) { 146611f2a477SManman Ren if (Module && Module->HasIncompatibleModuleFile) { 14678a308ec2SRichard Smith // We tried and failed to load a module file for this module. Fall 14688a308ec2SRichard Smith // back to textual inclusion for its headers. 14698a308ec2SRichard Smith return ModuleLoadResult(nullptr, /*missingExpected*/true); 14708a308ec2SRichard Smith } 14718a308ec2SRichard Smith 1472d2e8b04dSManuel Klimek getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled) 1473d2e8b04dSManuel Klimek << ModuleName; 1474d2e8b04dSManuel Klimek ModuleBuildFailed = true; 1475d2e8b04dSManuel Klimek return ModuleLoadResult(); 1476d2e8b04dSManuel Klimek } 1477d4b230b3SRichard Smith 147808142534SDouglas Gregor // If we don't already have an ASTReader, create one now. 14792255f2ceSJohn Thompson if (!ModuleManager) 14802255f2ceSJohn Thompson createModuleManager(); 148108142534SDouglas Gregor 1482ce18a187SRichard Smith llvm::Timer Timer; 1483ce18a187SRichard Smith if (FrontendTimerGroup) 1484ce18a187SRichard Smith Timer.init("Loading " + ModuleFileName, *FrontendTimerGroup); 1485ce18a187SRichard Smith llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); 1486ce18a187SRichard Smith 148711f2a477SManman Ren // Try to load the module file. If we are trying to load from the prebuilt 148811f2a477SManman Ren // module path, we don't have the module map files and don't know how to 148911f2a477SManman Ren // rebuild modules. 149011f2a477SManman Ren unsigned ARRFlags = LoadFromPrebuiltModulePath ? 149111f2a477SManman Ren ASTReader::ARR_ConfigurationMismatch : 149211f2a477SManman Ren ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; 1493e842a474SRichard Smith switch (ModuleManager->ReadAST(ModuleFileName, 149411f2a477SManman Ren LoadFromPrebuiltModulePath ? 149511f2a477SManman Ren serialization::MK_PrebuiltModule : 149686cc8290SRichard Smith serialization::MK_ImplicitModule, 149711f2a477SManman Ren ImportLoc, 149811f2a477SManman Ren ARRFlags)) { 149911f2a477SManman Ren case ASTReader::Success: { 150011f2a477SManman Ren if (LoadFromPrebuiltModulePath && !Module) { 150111f2a477SManman Ren Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 150211f2a477SManman Ren if (!Module || !Module->getASTFile() || 150311f2a477SManman Ren FileMgr->getFile(ModuleFileName) != Module->getASTFile()) { 150411f2a477SManman Ren // Error out if Module does not refer to the file in the prebuilt 150511f2a477SManman Ren // module path. 150611f2a477SManman Ren getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt) 150711f2a477SManman Ren << ModuleName; 150811f2a477SManman Ren ModuleBuildFailed = true; 150911f2a477SManman Ren KnownModules[Path[0].first] = nullptr; 151011f2a477SManman Ren return ModuleLoadResult(); 151111f2a477SManman Ren } 151211f2a477SManman Ren } 151308142534SDouglas Gregor break; 151411f2a477SManman Ren } 151508142534SDouglas Gregor 1516963ff2c3SEli Friedman case ASTReader::OutOfDate: 15177029ce1aSDouglas Gregor case ASTReader::Missing: { 151811f2a477SManman Ren if (LoadFromPrebuiltModulePath) { 151911f2a477SManman Ren // We can't rebuild the module without a module map. Since ReadAST 152011f2a477SManman Ren // already produces diagnostics for these two cases, we simply 152111f2a477SManman Ren // error out here. 152211f2a477SManman Ren ModuleBuildFailed = true; 152311f2a477SManman Ren KnownModules[Path[0].first] = nullptr; 152411f2a477SManman Ren return ModuleLoadResult(); 152511f2a477SManman Ren } 152611f2a477SManman Ren 1527963ff2c3SEli Friedman // The module file is missing or out-of-date. Build it. 15289eb229bfSBen Langmuir assert(Module && "missing module file"); 15297029ce1aSDouglas Gregor // Check whether there is a cycle in the module graph. 15307029ce1aSDouglas Gregor ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack(); 15317029ce1aSDouglas Gregor ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end(); 15327029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 15337029ce1aSDouglas Gregor if (Pos->first == ModuleName) 15347029ce1aSDouglas Gregor break; 15357029ce1aSDouglas Gregor } 15367029ce1aSDouglas Gregor 15377029ce1aSDouglas Gregor if (Pos != PosEnd) { 15387029ce1aSDouglas Gregor SmallString<256> CyclePath; 15397029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 15407029ce1aSDouglas Gregor CyclePath += Pos->first; 15417029ce1aSDouglas Gregor CyclePath += " -> "; 15427029ce1aSDouglas Gregor } 15437029ce1aSDouglas Gregor CyclePath += ModuleName; 15447029ce1aSDouglas Gregor 15457029ce1aSDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) 15467029ce1aSDouglas Gregor << ModuleName << CyclePath; 15477029ce1aSDouglas Gregor return ModuleLoadResult(); 15487029ce1aSDouglas Gregor } 15497a626570SDouglas Gregor 15507a626570SDouglas Gregor // Check whether we have already attempted to build this module (but 15517a626570SDouglas Gregor // failed). 15527a626570SDouglas Gregor if (getPreprocessorOpts().FailedModules && 15537a626570SDouglas Gregor getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { 15547a626570SDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) 15557a626570SDouglas Gregor << ModuleName 15567a626570SDouglas Gregor << SourceRange(ImportLoc, ModuleNameLoc); 1557c1bbec85SDouglas Gregor ModuleBuildFailed = true; 15587a626570SDouglas Gregor return ModuleLoadResult(); 15597a626570SDouglas Gregor } 15607a626570SDouglas Gregor 1561dbdc0368SBen Langmuir // Try to compile and then load the module. 1562dbdc0368SBen Langmuir if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module, 1563dbdc0368SBen Langmuir ModuleFileName)) { 1564d213aab7SBen Langmuir assert(getDiagnostics().hasErrorOccurred() && 1565d213aab7SBen Langmuir "undiagnosed error in compileAndLoadModule"); 15660f2b4635SDouglas Gregor if (getPreprocessorOpts().FailedModules) 15677a626570SDouglas Gregor getPreprocessorOpts().FailedModules->addFailed(ModuleName); 156849a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 1569c1bbec85SDouglas Gregor ModuleBuildFailed = true; 15707a626570SDouglas Gregor return ModuleLoadResult(); 1571188dbef2SDouglas Gregor } 1572188dbef2SDouglas Gregor 1573188dbef2SDouglas Gregor // Okay, we've rebuilt and now loaded the module. 1574188dbef2SDouglas Gregor break; 1575188dbef2SDouglas Gregor } 1576188dbef2SDouglas Gregor 1577c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 157811f2a477SManman Ren if (LoadFromPrebuiltModulePath) 157911f2a477SManman Ren getDiagnostics().Report(SourceLocation(), 158011f2a477SManman Ren diag::warn_module_config_mismatch) 158111f2a477SManman Ren << ModuleFileName; 158211f2a477SManman Ren // Fall through to error out. 158311f2a477SManman Ren case ASTReader::VersionMismatch: 1584c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 1585dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 15860f99d6a4SRichard Smith // FIXME: The ASTReader will already have complained, but can we shoehorn 158708142534SDouglas Gregor // that diagnostic information into a more useful form? 158849a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 15897a626570SDouglas Gregor return ModuleLoadResult(); 159008142534SDouglas Gregor 159108142534SDouglas Gregor case ASTReader::Failure: 1592dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 159369021974SDouglas Gregor // Already complained, but note now that we failed. 159449a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 1595c1bbec85SDouglas Gregor ModuleBuildFailed = true; 15967a626570SDouglas Gregor return ModuleLoadResult(); 159708142534SDouglas Gregor } 159808142534SDouglas Gregor 159969021974SDouglas Gregor // Cache the result of this top-level module lookup for later. 160069021974SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 160169021974SDouglas Gregor } 160269021974SDouglas Gregor 160369021974SDouglas Gregor // If we never found the module, fail. 160469021974SDouglas Gregor if (!Module) 16057a626570SDouglas Gregor return ModuleLoadResult(); 160669021974SDouglas Gregor 16075196bc6bSDouglas Gregor // Verify that the rest of the module path actually corresponds to 16085196bc6bSDouglas Gregor // a submodule. 160969021974SDouglas Gregor if (Path.size() > 1) { 16105196bc6bSDouglas Gregor for (unsigned I = 1, N = Path.size(); I != N; ++I) { 16115196bc6bSDouglas Gregor StringRef Name = Path[I].first->getName(); 1612eb90e830SDouglas Gregor clang::Module *Sub = Module->findSubmodule(Name); 16135196bc6bSDouglas Gregor 1614eb90e830SDouglas Gregor if (!Sub) { 16155196bc6bSDouglas Gregor // Attempt to perform typo correction to find a module name that works. 1616f857950dSDmitri Gribenko SmallVector<StringRef, 2> Best; 16175196bc6bSDouglas Gregor unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); 16185196bc6bSDouglas Gregor 1619eb90e830SDouglas Gregor for (clang::Module::submodule_iterator J = Module->submodule_begin(), 1620eb90e830SDouglas Gregor JEnd = Module->submodule_end(); 1621eb44edadSMatt Beaumont-Gay J != JEnd; ++J) { 1622eb90e830SDouglas Gregor unsigned ED = Name.edit_distance((*J)->Name, 16235196bc6bSDouglas Gregor /*AllowReplacements=*/true, 16245196bc6bSDouglas Gregor BestEditDistance); 16255196bc6bSDouglas Gregor if (ED <= BestEditDistance) { 1626eb90e830SDouglas Gregor if (ED < BestEditDistance) { 16275196bc6bSDouglas Gregor Best.clear(); 1628eb90e830SDouglas Gregor BestEditDistance = ED; 1629eb90e830SDouglas Gregor } 1630eb90e830SDouglas Gregor 1631eb90e830SDouglas Gregor Best.push_back((*J)->Name); 16325196bc6bSDouglas Gregor } 16335196bc6bSDouglas Gregor } 16345196bc6bSDouglas Gregor 16355196bc6bSDouglas Gregor // If there was a clear winner, user it. 16365196bc6bSDouglas Gregor if (Best.size() == 1) { 16375196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, 16385196bc6bSDouglas Gregor diag::err_no_submodule_suggest) 163969021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() << Best[0] 16405196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second) 16415196bc6bSDouglas Gregor << FixItHint::CreateReplacement(SourceRange(Path[I].second), 16425196bc6bSDouglas Gregor Best[0]); 1643eb90e830SDouglas Gregor 1644eb90e830SDouglas Gregor Sub = Module->findSubmodule(Best[0]); 16455196bc6bSDouglas Gregor } 16465196bc6bSDouglas Gregor } 16475196bc6bSDouglas Gregor 1648eb90e830SDouglas Gregor if (!Sub) { 16495196bc6bSDouglas Gregor // No submodule by this name. Complain, and don't look for further 16505196bc6bSDouglas Gregor // submodules. 16515196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, diag::err_no_submodule) 165269021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() 16535196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second); 16545196bc6bSDouglas Gregor break; 16555196bc6bSDouglas Gregor } 16565196bc6bSDouglas Gregor 1657eb90e830SDouglas Gregor Module = Sub; 16585196bc6bSDouglas Gregor } 16595196bc6bSDouglas Gregor } 16605196bc6bSDouglas Gregor 16612537a364SDouglas Gregor // Make the named module visible, if it's not already part of the module 16622537a364SDouglas Gregor // we are parsing. 166398a52db8SDouglas Gregor if (ModuleName != getLangOpts().CurrentModule) { 166498a52db8SDouglas Gregor if (!Module->IsFromModuleFile) { 166598a52db8SDouglas Gregor // We have an umbrella header or directory that doesn't actually include 166698a52db8SDouglas Gregor // all of the headers within the directory it covers. Complain about 166798a52db8SDouglas Gregor // this missing submodule and recover by forgetting that we ever saw 166898a52db8SDouglas Gregor // this submodule. 166998a52db8SDouglas Gregor // FIXME: Should we detect this at module load time? It seems fairly 167098a52db8SDouglas Gregor // expensive (and rare). 167198a52db8SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) 167298a52db8SDouglas Gregor << Module->getFullModuleName() 167398a52db8SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 167498a52db8SDouglas Gregor 167549a2790fSCraig Topper return ModuleLoadResult(nullptr, true); 167698a52db8SDouglas Gregor } 16771fb5c3a6SDouglas Gregor 16781fb5c3a6SDouglas Gregor // Check whether this module is available. 1679a3feee2aSRichard Smith clang::Module::Requirement Requirement; 16803c1a41adSRichard Smith clang::Module::UnresolvedHeaderDirective MissingHeader; 16810761a8a0SDaniel Jasper if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement, 16820761a8a0SDaniel Jasper MissingHeader)) { 16830761a8a0SDaniel Jasper if (MissingHeader.FileNameLoc.isValid()) { 16840761a8a0SDaniel Jasper getDiagnostics().Report(MissingHeader.FileNameLoc, 16850761a8a0SDaniel Jasper diag::err_module_header_missing) 16860761a8a0SDaniel Jasper << MissingHeader.IsUmbrella << MissingHeader.FileName; 16870761a8a0SDaniel Jasper } else { 16881fb5c3a6SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) 16891fb5c3a6SDouglas Gregor << Module->getFullModuleName() 1690a3feee2aSRichard Smith << Requirement.second << Requirement.first 16911fb5c3a6SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 16920761a8a0SDaniel Jasper } 16931fb5c3a6SDouglas Gregor LastModuleImportLoc = ImportLoc; 16947a626570SDouglas Gregor LastModuleImportResult = ModuleLoadResult(); 16957a626570SDouglas Gregor return ModuleLoadResult(); 16961fb5c3a6SDouglas Gregor } 16971fb5c3a6SDouglas Gregor 1698a7e2cc68SRichard Smith ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc); 169998a52db8SDouglas Gregor } 17005196bc6bSDouglas Gregor 170135b13eceSDouglas Gregor // Check for any configuration macros that have changed. 170235b13eceSDouglas Gregor clang::Module *TopModule = Module->getTopLevelModule(); 170335b13eceSDouglas Gregor for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) { 170435b13eceSDouglas Gregor checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I], 170535b13eceSDouglas Gregor Module, ImportLoc); 170635b13eceSDouglas Gregor } 170735b13eceSDouglas Gregor 17081805b8a4SDouglas Gregor LastModuleImportLoc = ImportLoc; 17097a626570SDouglas Gregor LastModuleImportResult = ModuleLoadResult(Module, false); 17107a626570SDouglas Gregor return LastModuleImportResult; 171108142534SDouglas Gregor } 1712c147b0bcSDouglas Gregor 1713c147b0bcSDouglas Gregor void CompilerInstance::makeModuleVisible(Module *Mod, 1714125df058SArgyrios Kyrtzidis Module::NameVisibilityKind Visibility, 1715a7e2cc68SRichard Smith SourceLocation ImportLoc) { 171642413141SRichard Smith if (!ModuleManager) 171742413141SRichard Smith createModuleManager(); 171842413141SRichard Smith if (!ModuleManager) 171942413141SRichard Smith return; 172042413141SRichard Smith 1721a7e2cc68SRichard Smith ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc); 1722c147b0bcSDouglas Gregor } 1723c147b0bcSDouglas Gregor 17242255f2ceSJohn Thompson GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( 17252255f2ceSJohn Thompson SourceLocation TriggerLoc) { 17263938f0c7SRichard Smith if (getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty()) 17273938f0c7SRichard Smith return nullptr; 17282255f2ceSJohn Thompson if (!ModuleManager) 17292255f2ceSJohn Thompson createModuleManager(); 17302255f2ceSJohn Thompson // Can't do anything if we don't have the module manager. 17312255f2ceSJohn Thompson if (!ModuleManager) 173249a2790fSCraig Topper return nullptr; 17332255f2ceSJohn Thompson // Get an existing global index. This loads it if not already 17342255f2ceSJohn Thompson // loaded. 17352255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 17362255f2ceSJohn Thompson GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex(); 17372255f2ceSJohn Thompson // If the global index doesn't exist, create it. 17382255f2ceSJohn Thompson if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() && 17392255f2ceSJohn Thompson hasPreprocessor()) { 17402255f2ceSJohn Thompson llvm::sys::fs::create_directories( 17412255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 17422255f2ceSJohn Thompson GlobalModuleIndex::writeIndex( 1743fb2398d0SAdrian Prantl getFileManager(), getPCHContainerReader(), 17442255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 17452255f2ceSJohn Thompson ModuleManager->resetForReload(); 17462255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 17472255f2ceSJohn Thompson GlobalIndex = ModuleManager->getGlobalIndex(); 17482255f2ceSJohn Thompson } 17492255f2ceSJohn Thompson // For finding modules needing to be imported for fixit messages, 17502255f2ceSJohn Thompson // we need to make the global index cover all modules, so we do that here. 17512255f2ceSJohn Thompson if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) { 17522255f2ceSJohn Thompson ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap(); 17532255f2ceSJohn Thompson bool RecreateIndex = false; 17542255f2ceSJohn Thompson for (ModuleMap::module_iterator I = MMap.module_begin(), 17552255f2ceSJohn Thompson E = MMap.module_end(); I != E; ++I) { 17562255f2ceSJohn Thompson Module *TheModule = I->second; 17572255f2ceSJohn Thompson const FileEntry *Entry = TheModule->getASTFile(); 17582255f2ceSJohn Thompson if (!Entry) { 17592255f2ceSJohn Thompson SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; 17602255f2ceSJohn Thompson Path.push_back(std::make_pair( 17612255f2ceSJohn Thompson getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc)); 17622255f2ceSJohn Thompson std::reverse(Path.begin(), Path.end()); 17632255f2ceSJohn Thompson // Load a module as hidden. This also adds it to the global index. 1764629d8e6fSRichard Smith loadModule(TheModule->DefinitionLoc, Path, Module::Hidden, false); 17652255f2ceSJohn Thompson RecreateIndex = true; 17662255f2ceSJohn Thompson } 17672255f2ceSJohn Thompson } 17682255f2ceSJohn Thompson if (RecreateIndex) { 17692255f2ceSJohn Thompson GlobalModuleIndex::writeIndex( 1770fb2398d0SAdrian Prantl getFileManager(), getPCHContainerReader(), 17712255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 17722255f2ceSJohn Thompson ModuleManager->resetForReload(); 17732255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 17742255f2ceSJohn Thompson GlobalIndex = ModuleManager->getGlobalIndex(); 17752255f2ceSJohn Thompson } 17762255f2ceSJohn Thompson HaveFullGlobalModuleIndex = true; 17772255f2ceSJohn Thompson } 17782255f2ceSJohn Thompson return GlobalIndex; 17792255f2ceSJohn Thompson } 17802d94bbb0SJohn Thompson 17812d94bbb0SJohn Thompson // Check global module index for missing imports. 17822d94bbb0SJohn Thompson bool 17832d94bbb0SJohn Thompson CompilerInstance::lookupMissingImports(StringRef Name, 17842d94bbb0SJohn Thompson SourceLocation TriggerLoc) { 17852d94bbb0SJohn Thompson // Look for the symbol in non-imported modules, but only if an error 17862d94bbb0SJohn Thompson // actually occurred. 17872d94bbb0SJohn Thompson if (!buildingModule()) { 17882d94bbb0SJohn Thompson // Load global module index, or retrieve a previously loaded one. 17892d94bbb0SJohn Thompson GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex( 17902d94bbb0SJohn Thompson TriggerLoc); 17912d94bbb0SJohn Thompson 17922d94bbb0SJohn Thompson // Only if we have a global index. 17932d94bbb0SJohn Thompson if (GlobalIndex) { 17942d94bbb0SJohn Thompson GlobalModuleIndex::HitSet FoundModules; 17952d94bbb0SJohn Thompson 17962d94bbb0SJohn Thompson // Find the modules that reference the identifier. 17972d94bbb0SJohn Thompson // Note that this only finds top-level modules. 17982d94bbb0SJohn Thompson // We'll let diagnoseTypo find the actual declaration module. 17992d94bbb0SJohn Thompson if (GlobalIndex->lookupIdentifier(Name, FoundModules)) 18002d94bbb0SJohn Thompson return true; 18012d94bbb0SJohn Thompson } 18022d94bbb0SJohn Thompson } 18032d94bbb0SJohn Thompson 18042d94bbb0SJohn Thompson return false; 18052d94bbb0SJohn Thompson } 1806a97eaa1bSDavid Blaikie void CompilerInstance::resetAndLeakSema() { BuryPointer(takeSema()); } 1807