1636404a3SDaniel Dunbar //===--- CompilerInstance.cpp ---------------------------------------------===//
2636404a3SDaniel Dunbar //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6636404a3SDaniel Dunbar //
7636404a3SDaniel Dunbar //===----------------------------------------------------------------------===//
8636404a3SDaniel Dunbar 
9636404a3SDaniel Dunbar #include "clang/Frontend/CompilerInstance.h"
1056d9c293SDaniel Dunbar #include "clang/AST/ASTConsumer.h"
11df3e30c4SDaniel Dunbar #include "clang/AST/ASTContext.h"
12bcfc7d02SDouglas Gregor #include "clang/AST/Decl.h"
139565c75bSRichard Smith #include "clang/Basic/CharInfo.h"
14636404a3SDaniel Dunbar #include "clang/Basic/Diagnostic.h"
15546a676aSDaniel Dunbar #include "clang/Basic/FileManager.h"
1609d890d7SRainer Orth #include "clang/Basic/LangStandard.h"
17546a676aSDaniel Dunbar #include "clang/Basic/SourceManager.h"
180a7b297dSRichard Smith #include "clang/Basic/Stack.h"
19636404a3SDaniel Dunbar #include "clang/Basic/TargetInfo.h"
204f2bc55dSDaniel Dunbar #include "clang/Basic/Version.h"
21f988d006SAlp Toker #include "clang/Config/config.h"
228b00dcb0SDavid Blaikie #include "clang/Frontend/ChainedDiagnosticConsumer.h"
234f2bc55dSDaniel Dunbar #include "clang/Frontend/FrontendAction.h"
24faeb1d46SDouglas Gregor #include "clang/Frontend/FrontendActions.h"
25f7093b5aSDaniel Dunbar #include "clang/Frontend/FrontendDiagnostic.h"
26f4f9ad0fSVassil Vassilev #include "clang/Frontend/FrontendPluginRegistry.h"
272083c32fSDaniel Dunbar #include "clang/Frontend/LogDiagnosticPrinter.h"
284610ea2bSTed Kremenek #include "clang/Frontend/SerializedDiagnosticPrinter.h"
297d75afc5SDaniel Dunbar #include "clang/Frontend/TextDiagnosticPrinter.h"
30aaa148fdSDaniel Dunbar #include "clang/Frontend/Utils.h"
313a02247dSChandler Carruth #include "clang/Frontend/VerifyDiagnosticConsumer.h"
323a02247dSChandler Carruth #include "clang/Lex/HeaderSearch.h"
333a02247dSChandler Carruth #include "clang/Lex/Preprocessor.h"
349670f847SMehdi Amini #include "clang/Lex/PreprocessorOptions.h"
35f7093b5aSDaniel Dunbar #include "clang/Sema/CodeCompleteConsumer.h"
363a02247dSChandler Carruth #include "clang/Sema/Sema.h"
373a02247dSChandler Carruth #include "clang/Serialization/ASTReader.h"
382255f2ceSJohn Thompson #include "clang/Serialization/GlobalModuleIndex.h"
398bef5cd4SDuncan P. N. Exon Smith #include "clang/Serialization/InMemoryModuleCache.h"
4076cb4cd0SJan Svoboda #include "llvm/ADT/ScopeExit.h"
41171b780cSDouglas Gregor #include "llvm/ADT/Statistic.h"
429941da41SDavid Blaikie #include "llvm/Support/BuryPointer.h"
433a02247dSChandler Carruth #include "llvm/Support/CrashRecoveryContext.h"
4471de0b61SRafael Espindola #include "llvm/Support/Errc.h"
453a02247dSChandler Carruth #include "llvm/Support/FileSystem.h"
468aaf4995SMichael J. Spencer #include "llvm/Support/Host.h"
47e212489fSDouglas Gregor #include "llvm/Support/LockFileManager.h"
483a02247dSChandler Carruth #include "llvm/Support/MemoryBuffer.h"
498aaf4995SMichael J. Spencer #include "llvm/Support/Path.h"
508aaf4995SMichael J. Spencer #include "llvm/Support/Program.h"
518aaf4995SMichael J. Spencer #include "llvm/Support/Signals.h"
52d880de2dSAnton Afanasyev #include "llvm/Support/TimeProfiler.h"
533a02247dSChandler Carruth #include "llvm/Support/Timer.h"
543a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h"
5537da327cSDouglas Gregor #include <time.h>
56cfeacf56SBenjamin Kramer #include <utility>
5754a88810SDouglas Gregor 
58636404a3SDaniel Dunbar using namespace clang;
59636404a3SDaniel Dunbar 
CompilerInstance(std::shared_ptr<PCHContainerOperations> PCHContainerOps,InMemoryModuleCache * SharedModuleCache)60bb165fb0SAdrian Prantl CompilerInstance::CompilerInstance(
61bb165fb0SAdrian Prantl     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
628bef5cd4SDuncan P. N. Exon Smith     InMemoryModuleCache *SharedModuleCache)
638bef5cd4SDuncan P. N. Exon Smith     : ModuleLoader(/* BuildingModule = */ SharedModuleCache),
64030d7d6dSDuncan P. N. Exon Smith       Invocation(new CompilerInvocation()),
658bef5cd4SDuncan P. N. Exon Smith       ModuleCache(SharedModuleCache ? SharedModuleCache
668bef5cd4SDuncan P. N. Exon Smith                                     : new InMemoryModuleCache),
670a2be46cSDuncan P. N. Exon Smith       ThePCHContainerOperations(std::move(PCHContainerOps)) {}
68636404a3SDaniel Dunbar 
~CompilerInstance()69636404a3SDaniel Dunbar CompilerInstance::~CompilerInstance() {
703c717b45SBenjamin Kramer   assert(OutputFiles.empty() && "Still output files in flight?");
71e922d9bdSDaniel Dunbar }
72e922d9bdSDaniel Dunbar 
setInvocation(std::shared_ptr<CompilerInvocation> Value)73ea4395ebSDavid Blaikie void CompilerInstance::setInvocation(
74ea4395ebSDavid Blaikie     std::shared_ptr<CompilerInvocation> Value) {
75ea4395ebSDavid Blaikie   Invocation = std::move(Value);
7668242254SDaniel Dunbar }
7768242254SDaniel Dunbar 
shouldBuildGlobalModuleIndex() const78c1bbec85SDouglas Gregor bool CompilerInstance::shouldBuildGlobalModuleIndex() const {
79e060e57bSDouglas Gregor   return (BuildGlobalModuleIndex ||
8020d51b2fSDuncan P. N. Exon Smith           (TheASTReader && TheASTReader->isGlobalIndexUnavailable() &&
8111ef0b77SDouglas Gregor            getFrontendOpts().GenerateGlobalModuleIndex)) &&
8223e9146fSDuncan P. N. Exon Smith          !DisableGeneratingGlobalModuleIndex;
83c1bbec85SDouglas Gregor }
84c1bbec85SDouglas Gregor 
setDiagnostics(DiagnosticsEngine * Value)859c902b55SDavid Blaikie void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) {
867f95d26eSDouglas Gregor   Diagnostics = Value;
87e01dc86dSDaniel Dunbar }
88e01dc86dSDaniel Dunbar 
setVerboseOutputStream(raw_ostream & Value)8987cb734cSScott Linder void CompilerInstance::setVerboseOutputStream(raw_ostream &Value) {
908afabff6SDuncan P. N. Exon Smith   OwnedVerboseOutputStream.reset();
9187cb734cSScott Linder   VerboseOutputStream = &Value;
9287cb734cSScott Linder }
9387cb734cSScott Linder 
setVerboseOutputStream(std::unique_ptr<raw_ostream> Value)9487cb734cSScott Linder void CompilerInstance::setVerboseOutputStream(std::unique_ptr<raw_ostream> Value) {
9587cb734cSScott Linder   OwnedVerboseOutputStream.swap(Value);
9687cb734cSScott Linder   VerboseOutputStream = OwnedVerboseOutputStream.get();
9787cb734cSScott Linder }
9887cb734cSScott Linder 
setTarget(TargetInfo * Value)99b5bc923aSArtem Belevich void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; }
setAuxTarget(TargetInfo * Value)100b5bc923aSArtem Belevich void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }
101e01dc86dSDaniel Dunbar 
createTarget()102d412dbe3SYu-Hsun Chiang bool CompilerInstance::createTarget() {
103d412dbe3SYu-Hsun Chiang   // Create the target instance.
104d412dbe3SYu-Hsun Chiang   setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(),
105d412dbe3SYu-Hsun Chiang                                          getInvocation().TargetOpts));
106d412dbe3SYu-Hsun Chiang   if (!hasTarget())
107d412dbe3SYu-Hsun Chiang     return false;
108d412dbe3SYu-Hsun Chiang 
109fc1117dfSoToToT   // Check whether AuxTarget exists, if not, then create TargetInfo for the
110fc1117dfSoToToT   // other side of CUDA/OpenMP/SYCL compilation.
111fc1117dfSoToToT   if (!getAuxTarget() &&
112fc1117dfSoToToT       (getLangOpts().CUDA || getLangOpts().OpenMPIsDevice ||
113d412dbe3SYu-Hsun Chiang        getLangOpts().SYCLIsDevice) &&
114d412dbe3SYu-Hsun Chiang       !getFrontendOpts().AuxTriple.empty()) {
115d412dbe3SYu-Hsun Chiang     auto TO = std::make_shared<TargetOptions>();
116d412dbe3SYu-Hsun Chiang     TO->Triple = llvm::Triple::normalize(getFrontendOpts().AuxTriple);
117d412dbe3SYu-Hsun Chiang     if (getFrontendOpts().AuxTargetCPU)
118*cb2c8f69SKazu Hirata       TO->CPU = getFrontendOpts().AuxTargetCPU.value();
119d412dbe3SYu-Hsun Chiang     if (getFrontendOpts().AuxTargetFeatures)
120*cb2c8f69SKazu Hirata       TO->FeaturesAsWritten = getFrontendOpts().AuxTargetFeatures.value();
121d412dbe3SYu-Hsun Chiang     TO->HostTriple = getTarget().getTriple().str();
122d412dbe3SYu-Hsun Chiang     setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO));
123d412dbe3SYu-Hsun Chiang   }
124d412dbe3SYu-Hsun Chiang 
125d412dbe3SYu-Hsun Chiang   if (!getTarget().hasStrictFP() && !getLangOpts().ExpStrictFP) {
126706e89dbSSerge Pavlov     if (getLangOpts().RoundingMath) {
127d412dbe3SYu-Hsun Chiang       getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_rounding);
128706e89dbSSerge Pavlov       getLangOpts().RoundingMath = false;
129d412dbe3SYu-Hsun Chiang     }
130706e89dbSSerge Pavlov     auto FPExc = getLangOpts().getFPExceptionMode();
131706e89dbSSerge Pavlov     if (FPExc != LangOptions::FPE_Default && FPExc != LangOptions::FPE_Ignore) {
132d412dbe3SYu-Hsun Chiang       getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_exceptions);
133d412dbe3SYu-Hsun Chiang       getLangOpts().setFPExceptionMode(LangOptions::FPE_Ignore);
134d412dbe3SYu-Hsun Chiang     }
135d412dbe3SYu-Hsun Chiang     // FIXME: can we disable FEnvAccess?
136d412dbe3SYu-Hsun Chiang   }
137d412dbe3SYu-Hsun Chiang 
138f0efc007SAnton Zabaznov   // We should do it here because target knows nothing about
139f0efc007SAnton Zabaznov   // language options when it's being created.
14082690578SAnton Zabaznov   if (getLangOpts().OpenCL &&
14182690578SAnton Zabaznov       !getTarget().validateOpenCLTarget(getLangOpts(), getDiagnostics()))
14282690578SAnton Zabaznov     return false;
143f0efc007SAnton Zabaznov 
144d412dbe3SYu-Hsun Chiang   // Inform the target of the language options.
145d412dbe3SYu-Hsun Chiang   // FIXME: We shouldn't need to do this, the target should be immutable once
146d412dbe3SYu-Hsun Chiang   // created. This complexity should be lifted elsewhere.
147aaba3718SMelanie Blower   getTarget().adjust(getDiagnostics(), getLangOpts());
148d412dbe3SYu-Hsun Chiang 
149d412dbe3SYu-Hsun Chiang   // Adjust target options based on codegen options.
150d412dbe3SYu-Hsun Chiang   getTarget().adjustTargetOptions(getCodeGenOpts(), getTargetOpts());
151d412dbe3SYu-Hsun Chiang 
152d412dbe3SYu-Hsun Chiang   if (auto *Aux = getAuxTarget())
153d412dbe3SYu-Hsun Chiang     getTarget().setAuxTarget(Aux);
154d412dbe3SYu-Hsun Chiang 
155d412dbe3SYu-Hsun Chiang   return true;
156d412dbe3SYu-Hsun Chiang }
157d412dbe3SYu-Hsun Chiang 
getVirtualFileSystem() const158e08464fbSReid Kleckner llvm::vfs::FileSystem &CompilerInstance::getVirtualFileSystem() const {
159e08464fbSReid Kleckner   return getFileManager().getVirtualFileSystem();
160e08464fbSReid Kleckner }
161e08464fbSReid Kleckner 
setFileManager(FileManager * Value)162e01dc86dSDaniel Dunbar void CompilerInstance::setFileManager(FileManager *Value) {
1635e14d39aSTed Kremenek   FileMgr = Value;
164e01dc86dSDaniel Dunbar }
165e01dc86dSDaniel Dunbar 
setSourceManager(SourceManager * Value)166e01dc86dSDaniel Dunbar void CompilerInstance::setSourceManager(SourceManager *Value) {
1675e14d39aSTed Kremenek   SourceMgr = Value;
168e01dc86dSDaniel Dunbar }
169e01dc86dSDaniel Dunbar 
setPreprocessor(std::shared_ptr<Preprocessor> Value)17041565463SDavid Blaikie void CompilerInstance::setPreprocessor(std::shared_ptr<Preprocessor> Value) {
17141565463SDavid Blaikie   PP = std::move(Value);
17241565463SDavid Blaikie }
173e01dc86dSDaniel Dunbar 
setASTContext(ASTContext * Value)174293534b1SRichard Smith void CompilerInstance::setASTContext(ASTContext *Value) {
175293534b1SRichard Smith   Context = Value;
176293534b1SRichard Smith 
177293534b1SRichard Smith   if (Context && Consumer)
178293534b1SRichard Smith     getASTConsumer().Initialize(getASTContext());
179293534b1SRichard Smith }
180e01dc86dSDaniel Dunbar 
setSema(Sema * S)1810e93f017SDouglas Gregor void CompilerInstance::setSema(Sema *S) {
1820e93f017SDouglas Gregor   TheSema.reset(S);
1830e93f017SDouglas Gregor }
1840e93f017SDouglas Gregor 
setASTConsumer(std::unique_ptr<ASTConsumer> Value)1856beb6aa8SDavid Blaikie void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) {
1866beb6aa8SDavid Blaikie   Consumer = std::move(Value);
187293534b1SRichard Smith 
188293534b1SRichard Smith   if (Context && Consumer)
189293534b1SRichard Smith     getASTConsumer().Initialize(getASTContext());
19056d9c293SDaniel Dunbar }
19156d9c293SDaniel Dunbar 
setCodeCompletionConsumer(CodeCompleteConsumer * Value)192e01dc86dSDaniel Dunbar void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
193e01dc86dSDaniel Dunbar   CompletionConsumer.reset(Value);
194e01dc86dSDaniel Dunbar }
195e01dc86dSDaniel Dunbar 
takeSema()1966153581aSDavid Blaikie std::unique_ptr<Sema> CompilerInstance::takeSema() {
1976153581aSDavid Blaikie   return std::move(TheSema);
1986153581aSDavid Blaikie }
1996153581aSDavid Blaikie 
getASTReader() const20020d51b2fSDuncan P. N. Exon Smith IntrusiveRefCntPtr<ASTReader> CompilerInstance::getASTReader() const {
20120d51b2fSDuncan P. N. Exon Smith   return TheASTReader;
2021b7ed91eSArgyrios Kyrtzidis }
setASTReader(IntrusiveRefCntPtr<ASTReader> Reader)203a6c86989SVolodymyr Sapsai void CompilerInstance::setASTReader(IntrusiveRefCntPtr<ASTReader> Reader) {
2048bef5cd4SDuncan P. N. Exon Smith   assert(ModuleCache.get() == &Reader->getModuleManager().getModuleCache() &&
205030d7d6dSDuncan P. N. Exon Smith          "Expected ASTReader to use the same PCM cache");
20620d51b2fSDuncan P. N. Exon Smith   TheASTReader = std::move(Reader);
2071b7ed91eSArgyrios Kyrtzidis }
2081b7ed91eSArgyrios Kyrtzidis 
20986d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector>
getModuleDepCollector() const21086d1259cSJustin Bogner CompilerInstance::getModuleDepCollector() const {
21186d1259cSJustin Bogner   return ModuleDepCollector;
21286d1259cSJustin Bogner }
21386d1259cSJustin Bogner 
setModuleDepCollector(std::shared_ptr<ModuleDependencyCollector> Collector)21486d1259cSJustin Bogner void CompilerInstance::setModuleDepCollector(
21586d1259cSJustin Bogner     std::shared_ptr<ModuleDependencyCollector> Collector) {
216d6da1a09SBenjamin Kramer   ModuleDepCollector = std::move(Collector);
21786d1259cSJustin Bogner }
21886d1259cSJustin Bogner 
collectHeaderMaps(const HeaderSearch & HS,std::shared_ptr<ModuleDependencyCollector> MDC)219181225b8SBruno Cardoso Lopes static void collectHeaderMaps(const HeaderSearch &HS,
220181225b8SBruno Cardoso Lopes                               std::shared_ptr<ModuleDependencyCollector> MDC) {
221181225b8SBruno Cardoso Lopes   SmallVector<std::string, 4> HeaderMapFileNames;
222181225b8SBruno Cardoso Lopes   HS.getHeaderMapFileNames(HeaderMapFileNames);
223181225b8SBruno Cardoso Lopes   for (auto &Name : HeaderMapFileNames)
224181225b8SBruno Cardoso Lopes     MDC->addFile(Name);
225181225b8SBruno Cardoso Lopes }
226181225b8SBruno Cardoso Lopes 
collectIncludePCH(CompilerInstance & CI,std::shared_ptr<ModuleDependencyCollector> MDC)2277aff2bb3SBruno Cardoso Lopes static void collectIncludePCH(CompilerInstance &CI,
2287aff2bb3SBruno Cardoso Lopes                               std::shared_ptr<ModuleDependencyCollector> MDC) {
2297aff2bb3SBruno Cardoso Lopes   const PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
2307aff2bb3SBruno Cardoso Lopes   if (PPOpts.ImplicitPCHInclude.empty())
2317aff2bb3SBruno Cardoso Lopes     return;
2327aff2bb3SBruno Cardoso Lopes 
2337aff2bb3SBruno Cardoso Lopes   StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
2347aff2bb3SBruno Cardoso Lopes   FileManager &FileMgr = CI.getFileManager();
23599b4874aSJan Svoboda   auto PCHDir = FileMgr.getOptionalDirectoryRef(PCHInclude);
2367aff2bb3SBruno Cardoso Lopes   if (!PCHDir) {
2377aff2bb3SBruno Cardoso Lopes     MDC->addFile(PCHInclude);
2387aff2bb3SBruno Cardoso Lopes     return;
2397aff2bb3SBruno Cardoso Lopes   }
2407aff2bb3SBruno Cardoso Lopes 
2417aff2bb3SBruno Cardoso Lopes   std::error_code EC;
2427aff2bb3SBruno Cardoso Lopes   SmallString<128> DirNative;
24399b4874aSJan Svoboda   llvm::sys::path::native(PCHDir->getName(), DirNative);
244db8a7422SDuncan P. N. Exon Smith   llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
2457aff2bb3SBruno Cardoso Lopes   SimpleASTReaderListener Validator(CI.getPreprocessor());
246fc51490bSJonas Devlieghere   for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
2477aff2bb3SBruno Cardoso Lopes        Dir != DirEnd && !EC; Dir.increment(EC)) {
2487aff2bb3SBruno Cardoso Lopes     // Check whether this is an AST file. ASTReader::isAcceptableASTFile is not
2497aff2bb3SBruno Cardoso Lopes     // used here since we're not interested in validating the PCH at this time,
2507aff2bb3SBruno Cardoso Lopes     // but only to check whether this is a file containing an AST.
2517aff2bb3SBruno Cardoso Lopes     if (!ASTReader::readASTFileControlBlock(
2520ae00567SSam McCall             Dir->path(), FileMgr, CI.getPCHContainerReader(),
2537aff2bb3SBruno Cardoso Lopes             /*FindModuleFileExtensions=*/false, Validator,
2547aff2bb3SBruno Cardoso Lopes             /*ValidateDiagnosticOptions=*/false))
2550ae00567SSam McCall       MDC->addFile(Dir->path());
2567aff2bb3SBruno Cardoso Lopes   }
2577aff2bb3SBruno Cardoso Lopes }
2587aff2bb3SBruno Cardoso Lopes 
collectVFSEntries(CompilerInstance & CI,std::shared_ptr<ModuleDependencyCollector> MDC)25982ec4fdeSBruno Cardoso Lopes static void collectVFSEntries(CompilerInstance &CI,
26082ec4fdeSBruno Cardoso Lopes                               std::shared_ptr<ModuleDependencyCollector> MDC) {
26182ec4fdeSBruno Cardoso Lopes   if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty())
26282ec4fdeSBruno Cardoso Lopes     return;
26382ec4fdeSBruno Cardoso Lopes 
26482ec4fdeSBruno Cardoso Lopes   // Collect all VFS found.
265fc51490bSJonas Devlieghere   SmallVector<llvm::vfs::YAMLVFSEntry, 16> VFSEntries;
26682ec4fdeSBruno Cardoso Lopes   for (const std::string &VFSFile : CI.getHeaderSearchOpts().VFSOverlayFiles) {
26782ec4fdeSBruno Cardoso Lopes     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
26882ec4fdeSBruno Cardoso Lopes         llvm::MemoryBuffer::getFile(VFSFile);
26982ec4fdeSBruno Cardoso Lopes     if (!Buffer)
27082ec4fdeSBruno Cardoso Lopes       return;
271fc51490bSJonas Devlieghere     llvm::vfs::collectVFSFromYAML(std::move(Buffer.get()),
272fc51490bSJonas Devlieghere                                   /*DiagHandler*/ nullptr, VFSFile, VFSEntries);
27382ec4fdeSBruno Cardoso Lopes   }
27482ec4fdeSBruno Cardoso Lopes 
27582ec4fdeSBruno Cardoso Lopes   for (auto &E : VFSEntries)
27682ec4fdeSBruno Cardoso Lopes     MDC->addFile(E.VPath, E.RPath);
27782ec4fdeSBruno Cardoso Lopes }
27882ec4fdeSBruno Cardoso Lopes 
2797d75afc5SDaniel Dunbar // Diagnostics
SetUpDiagnosticLog(DiagnosticOptions * DiagOpts,const CodeGenOptions * CodeGenOpts,DiagnosticsEngine & Diags)280811db4eaSDouglas Gregor static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
2817b83306dSDaniel Dunbar                                const CodeGenOptions *CodeGenOpts,
2829c902b55SDavid Blaikie                                DiagnosticsEngine &Diags) {
283dae941a6SRafael Espindola   std::error_code EC;
28411f8a943SDavid Blaikie   std::unique_ptr<raw_ostream> StreamOwner;
2850e62c1ccSChris Lattner   raw_ostream *OS = &llvm::errs();
286811db4eaSDouglas Gregor   if (DiagOpts->DiagnosticLogFile != "-") {
2872083c32fSDaniel Dunbar     // Create the output stream.
2882b3d49b6SJonas Devlieghere     auto FileOS = std::make_unique<llvm::raw_fd_ostream>(
289dae941a6SRafael Espindola         DiagOpts->DiagnosticLogFile, EC,
29082b3e28eSAbhina Sreeskantharajan         llvm::sys::fs::OF_Append | llvm::sys::fs::OF_TextWithCRLF);
291dae941a6SRafael Espindola     if (EC) {
2922083c32fSDaniel Dunbar       Diags.Report(diag::warn_fe_cc_log_diagnostics_failure)
293dae941a6SRafael Espindola           << DiagOpts->DiagnosticLogFile << EC.message();
2942083c32fSDaniel Dunbar     } else {
2952083c32fSDaniel Dunbar       FileOS->SetUnbuffered();
29611f8a943SDavid Blaikie       OS = FileOS.get();
29711f8a943SDavid Blaikie       StreamOwner = std::move(FileOS);
2982083c32fSDaniel Dunbar     }
2992083c32fSDaniel Dunbar   }
3002083c32fSDaniel Dunbar 
3012083c32fSDaniel Dunbar   // Chain in the diagnostic client which will log the diagnostics.
3022b3d49b6SJonas Devlieghere   auto Logger = std::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,
3037ee25502SDavid Blaikie                                                         std::move(StreamOwner));
3047b83306dSDaniel Dunbar   if (CodeGenOpts)
3057b83306dSDaniel Dunbar     Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags);
30688377d8dSAlex Lorenz   if (Diags.ownsClient()) {
30741c247a6SAlexander Kornienko     Diags.setClient(
30841c247a6SAlexander Kornienko         new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger)));
30988377d8dSAlex Lorenz   } else {
31088377d8dSAlex Lorenz     Diags.setClient(
31188377d8dSAlex Lorenz         new ChainedDiagnosticConsumer(Diags.getClient(), std::move(Logger)));
31288377d8dSAlex Lorenz   }
3132083c32fSDaniel Dunbar }
3142083c32fSDaniel Dunbar 
SetupSerializedDiagnostics(DiagnosticOptions * DiagOpts,DiagnosticsEngine & Diags,StringRef OutputFile)315811db4eaSDouglas Gregor static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts,
3164610ea2bSTed Kremenek                                        DiagnosticsEngine &Diags,
3174610ea2bSTed Kremenek                                        StringRef OutputFile) {
3187ee25502SDavid Blaikie   auto SerializedConsumer =
3195a6a2fcdSJustin Bogner       clang::serialized_diags::create(OutputFile, DiagOpts);
3204610ea2bSTed Kremenek 
321254b7dbaSAlexander Kornienko   if (Diags.ownsClient()) {
3227ee25502SDavid Blaikie     Diags.setClient(new ChainedDiagnosticConsumer(
32341c247a6SAlexander Kornienko         Diags.takeClient(), std::move(SerializedConsumer)));
324254b7dbaSAlexander Kornienko   } else {
325254b7dbaSAlexander Kornienko     Diags.setClient(new ChainedDiagnosticConsumer(
3264c0ef379SAlexander Kornienko         Diags.getClient(), std::move(SerializedConsumer)));
327254b7dbaSAlexander Kornienko   }
3284610ea2bSTed Kremenek }
3294610ea2bSTed Kremenek 
createDiagnostics(DiagnosticConsumer * Client,bool ShouldOwnClient)330f1b49e23SSean Silva void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client,
33130071ceaSDouglas Gregor                                          bool ShouldOwnClient) {
332f1b49e23SSean Silva   Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client,
33330071ceaSDouglas Gregor                                   ShouldOwnClient, &getCodeGenOpts());
3347d75afc5SDaniel Dunbar }
3357d75afc5SDaniel Dunbar 
336c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine>
createDiagnostics(DiagnosticOptions * Opts,DiagnosticConsumer * Client,bool ShouldOwnClient,const CodeGenOptions * CodeGenOpts)337811db4eaSDouglas Gregor CompilerInstance::createDiagnostics(DiagnosticOptions *Opts,
338e2eefaecSDavid Blaikie                                     DiagnosticConsumer *Client,
3392b9b4642SDouglas Gregor                                     bool ShouldOwnClient,
3407b83306dSDaniel Dunbar                                     const CodeGenOptions *CodeGenOpts) {
341c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
342c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticsEngine>
343811db4eaSDouglas Gregor       Diags(new DiagnosticsEngine(DiagID, Opts));
3441b39a2edSDaniel Dunbar 
3457d75afc5SDaniel Dunbar   // Create the diagnostic client for reporting errors or for
3467d75afc5SDaniel Dunbar   // implementing -verify.
347d0e9e3a6SDouglas Gregor   if (Client) {
348d0e9e3a6SDouglas Gregor     Diags->setClient(Client, ShouldOwnClient);
349d0e9e3a6SDouglas Gregor   } else
3502dd19f1dSDouglas Gregor     Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));
35150ec0da0SDaniel Dunbar 
35250ec0da0SDaniel Dunbar   // Chain in -verify checker, if requested.
353811db4eaSDouglas Gregor   if (Opts->VerifyDiagnostics)
35469609dceSDavid Blaikie     Diags->setClient(new VerifyDiagnosticConsumer(*Diags));
3557d75afc5SDaniel Dunbar 
3562083c32fSDaniel Dunbar   // Chain in -diagnostic-log-file dumper, if requested.
357811db4eaSDouglas Gregor   if (!Opts->DiagnosticLogFile.empty())
3587b83306dSDaniel Dunbar     SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags);
3592083c32fSDaniel Dunbar 
360811db4eaSDouglas Gregor   if (!Opts->DiagnosticSerializationFile.empty())
3614610ea2bSTed Kremenek     SetupSerializedDiagnostics(Opts, *Diags,
362811db4eaSDouglas Gregor                                Opts->DiagnosticSerializationFile);
3634610ea2bSTed Kremenek 
3647d75afc5SDaniel Dunbar   // Configure our handling of diagnostics.
365811db4eaSDouglas Gregor   ProcessWarningOptions(*Diags, *Opts);
3667d75afc5SDaniel Dunbar 
3677f95d26eSDouglas Gregor   return Diags;
3687d75afc5SDaniel Dunbar }
3697d75afc5SDaniel Dunbar 
3707d75afc5SDaniel Dunbar // File Manager
3717d75afc5SDaniel Dunbar 
createFileManager(IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)3721da7eac8SDuncan P. N. Exon Smith FileManager *CompilerInstance::createFileManager(
3731da7eac8SDuncan P. N. Exon Smith     IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
3741da7eac8SDuncan P. N. Exon Smith   if (!VFS)
375db8a7422SDuncan P. N. Exon Smith     VFS = FileMgr ? &FileMgr->getVirtualFileSystem()
3761da7eac8SDuncan P. N. Exon Smith                   : createVFSFromCompilerInvocation(getInvocation(),
3771da7eac8SDuncan P. N. Exon Smith                                                     getDiagnostics());
3781da7eac8SDuncan P. N. Exon Smith   assert(VFS && "FileManager has no VFS?");
3791da7eac8SDuncan P. N. Exon Smith   FileMgr = new FileManager(getFileSystemOpts(), std::move(VFS));
380abc3d04eSRaphael Isemann   return FileMgr.get();
381546a676aSDaniel Dunbar }
382546a676aSDaniel Dunbar 
3837d75afc5SDaniel Dunbar // Source Manager
3847d75afc5SDaniel Dunbar 
createSourceManager(FileManager & FileMgr)3855159f616SChris Lattner void CompilerInstance::createSourceManager(FileManager &FileMgr) {
3865e14d39aSTed Kremenek   SourceMgr = new SourceManager(getDiagnostics(), FileMgr);
387546a676aSDaniel Dunbar }
388aaa148fdSDaniel Dunbar 
389c358000eSAlp Toker // Initialize the remapping of files to alternative contents, e.g.,
390c358000eSAlp Toker // those specified through other files.
InitializeFileRemapping(DiagnosticsEngine & Diags,SourceManager & SourceMgr,FileManager & FileMgr,const PreprocessorOptions & InitOpts)391c358000eSAlp Toker static void InitializeFileRemapping(DiagnosticsEngine &Diags,
392c358000eSAlp Toker                                     SourceManager &SourceMgr,
393c358000eSAlp Toker                                     FileManager &FileMgr,
394c358000eSAlp Toker                                     const PreprocessorOptions &InitOpts) {
395c358000eSAlp Toker   // Remap files in the source manager (with buffers).
3961b070d25SAlp Toker   for (const auto &RB : InitOpts.RemappedFileBuffers) {
397c358000eSAlp Toker     // Create the file entry for the file that we're mapping from.
398c358000eSAlp Toker     const FileEntry *FromFile =
3991b070d25SAlp Toker         FileMgr.getVirtualFile(RB.first, RB.second->getBufferSize(), 0);
400c358000eSAlp Toker     if (!FromFile) {
4011b070d25SAlp Toker       Diags.Report(diag::err_fe_remap_missing_from_file) << RB.first;
402c358000eSAlp Toker       if (!InitOpts.RetainRemappedFileBuffers)
4031b070d25SAlp Toker         delete RB.second;
404c358000eSAlp Toker       continue;
405c358000eSAlp Toker     }
406c358000eSAlp Toker 
40729631451SDuncan P. N. Exon Smith     // Override the contents of the "from" file with the contents of the
40829631451SDuncan P. N. Exon Smith     // "to" file. If the caller owns the buffers, then pass a MemoryBufferRef;
40929631451SDuncan P. N. Exon Smith     // otherwise, pass as a std::unique_ptr<MemoryBuffer> to transfer ownership
41029631451SDuncan P. N. Exon Smith     // to the SourceManager.
41129631451SDuncan P. N. Exon Smith     if (InitOpts.RetainRemappedFileBuffers)
41229631451SDuncan P. N. Exon Smith       SourceMgr.overrideFileContents(FromFile, RB.second->getMemBufferRef());
41329631451SDuncan P. N. Exon Smith     else
41429631451SDuncan P. N. Exon Smith       SourceMgr.overrideFileContents(
41529631451SDuncan P. N. Exon Smith           FromFile, std::unique_ptr<llvm::MemoryBuffer>(
41629631451SDuncan P. N. Exon Smith                         const_cast<llvm::MemoryBuffer *>(RB.second)));
417c358000eSAlp Toker   }
418c358000eSAlp Toker 
419c358000eSAlp Toker   // Remap files in the source manager (with other files).
4201b070d25SAlp Toker   for (const auto &RF : InitOpts.RemappedFiles) {
421c358000eSAlp Toker     // Find the file that we're mapping to.
4228d323d15SHarlan Haskins     auto ToFile = FileMgr.getFile(RF.second);
423c358000eSAlp Toker     if (!ToFile) {
4241b070d25SAlp Toker       Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
425c358000eSAlp Toker       continue;
426c358000eSAlp Toker     }
427c358000eSAlp Toker 
428c358000eSAlp Toker     // Create the file entry for the file that we're mapping from.
429c358000eSAlp Toker     const FileEntry *FromFile =
4308d323d15SHarlan Haskins         FileMgr.getVirtualFile(RF.first, (*ToFile)->getSize(), 0);
431c358000eSAlp Toker     if (!FromFile) {
4321b070d25SAlp Toker       Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first;
433c358000eSAlp Toker       continue;
434c358000eSAlp Toker     }
435c358000eSAlp Toker 
436c358000eSAlp Toker     // Override the contents of the "from" file with the contents of
437c358000eSAlp Toker     // the "to" file.
4388d323d15SHarlan Haskins     SourceMgr.overrideFileContents(FromFile, *ToFile);
439c358000eSAlp Toker   }
440c358000eSAlp Toker 
441c358000eSAlp Toker   SourceMgr.setOverridenFilesKeepOriginalName(
442c358000eSAlp Toker       InitOpts.RemappedFilesKeepOriginalName);
443c358000eSAlp Toker }
444c358000eSAlp Toker 
4457d75afc5SDaniel Dunbar // Preprocessor
4467d75afc5SDaniel Dunbar 
createPreprocessor(TranslationUnitKind TUKind)447e1974dcdSArgyrios Kyrtzidis void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
44808142534SDouglas Gregor   const PreprocessorOptions &PPOpts = getPreprocessorOpts();
449aaa148fdSDaniel Dunbar 
450a6c86989SVolodymyr Sapsai   // The AST reader holds a reference to the old preprocessor (if any).
45120d51b2fSDuncan P. N. Exon Smith   TheASTReader.reset();
4525904c41eSBenjamin Kramer 
453aaa148fdSDaniel Dunbar   // Create the Preprocessor.
4549c28cb3fSDavid Blaikie   HeaderSearch *HeaderInfo =
4559c28cb3fSDavid Blaikie       new HeaderSearch(getHeaderSearchOptsPtr(), getSourceManager(),
4569c28cb3fSDavid Blaikie                        getDiagnostics(), getLangOpts(), &getTarget());
4578bef5cd4SDuncan P. N. Exon Smith   PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOptsPtr(),
4588bef5cd4SDuncan P. N. Exon Smith                                       getDiagnostics(), getLangOpts(),
4598bef5cd4SDuncan P. N. Exon Smith                                       getSourceManager(), *HeaderInfo, *this,
4600a6b5b65SErich Keane                                       /*IdentifierInfoLookup=*/nullptr,
4619663780eSAlp Toker                                       /*OwnsHeaderSearch=*/true, TUKind);
462aaba3718SMelanie Blower   getTarget().adjust(getDiagnostics(), getLangOpts());
463b5bc923aSArtem Belevich   PP->Initialize(getTarget(), getAuxTarget());
464aaa148fdSDaniel Dunbar 
4657f6d60dcSDouglas Gregor   if (PPOpts.DetailedRecord)
466f3d587eaSArgyrios Kyrtzidis     PP->createPreprocessingRecord();
4677f6d60dcSDouglas Gregor 
468c358000eSAlp Toker   // Apply remappings to the source manager.
469c358000eSAlp Toker   InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(),
470c358000eSAlp Toker                           PP->getFileManager(), PPOpts);
471c358000eSAlp Toker 
472c358000eSAlp Toker   // Predefine macros and configure the preprocessor.
473fb2398d0SAdrian Prantl   InitializePreprocessor(*PP, PPOpts, getPCHContainerReader(),
474bb165fb0SAdrian Prantl                          getFrontendOpts());
475c358000eSAlp Toker 
476f91086b0SJustin Lebar   // Initialize the header search object.  In CUDA compilations, we use the aux
477f91086b0SJustin Lebar   // triple (the host triple) to initialize our header search, since we need to
478f91086b0SJustin Lebar   // find the host headers in order to compile the CUDA code.
479f91086b0SJustin Lebar   const llvm::Triple *HeaderSearchTriple = &PP->getTargetInfo().getTriple();
480f91086b0SJustin Lebar   if (PP->getTargetInfo().getTriple().getOS() == llvm::Triple::CUDA &&
481f91086b0SJustin Lebar       PP->getAuxTargetInfo())
482f91086b0SJustin Lebar     HeaderSearchTriple = &PP->getAuxTargetInfo()->getTriple();
483f91086b0SJustin Lebar 
484c358000eSAlp Toker   ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(),
485f91086b0SJustin Lebar                            PP->getLangOpts(), *HeaderSearchTriple);
486aaa148fdSDaniel Dunbar 
48717441589SJordan Rose   PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP);
48817441589SJordan Rose 
48958c586e7SAlexandre Rames   if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) {
49058c586e7SAlexandre Rames     std::string ModuleHash = getInvocation().getModuleHash();
49158c586e7SAlexandre Rames     PP->getHeaderSearchInfo().setModuleHash(ModuleHash);
49258c586e7SAlexandre Rames     PP->getHeaderSearchInfo().setModuleCachePath(
49358c586e7SAlexandre Rames         getSpecificModuleCachePath(ModuleHash));
49458c586e7SAlexandre Rames   }
4951735f4e7SDouglas Gregor 
496aaa148fdSDaniel Dunbar   // Handle generating dependencies, if requested.
49708142534SDouglas Gregor   const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
498aaa148fdSDaniel Dunbar   if (!DepOpts.OutputFile.empty())
4998d9eb7acSAlex Lorenz     addDependencyCollector(std::make_shared<DependencyFileGenerator>(DepOpts));
5002e129659SDouglas Gregor   if (!DepOpts.DOTOutputFile.empty())
5012e129659SDouglas Gregor     AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,
50283d46be3SDouglas Gregor                              getHeaderSearchOpts().Sysroot);
50383d46be3SDouglas Gregor 
50486d1259cSJustin Bogner   // If we don't have a collector, but we are collecting module dependencies,
50586d1259cSJustin Bogner   // then we're the top level compiler instance and need to create one.
506b1631d91SBruno Cardoso Lopes   if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty()) {
50786d1259cSJustin Bogner     ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
50886d1259cSJustin Bogner         DepOpts.ModuleDependencyOutputDir);
509b1631d91SBruno Cardoso Lopes   }
510b1631d91SBruno Cardoso Lopes 
511181225b8SBruno Cardoso Lopes   // If there is a module dep collector, register with other dep collectors
512181225b8SBruno Cardoso Lopes   // and also (a) collect header maps and (b) TODO: input vfs overlay files.
513181225b8SBruno Cardoso Lopes   if (ModuleDepCollector) {
514b1631d91SBruno Cardoso Lopes     addDependencyCollector(ModuleDepCollector);
515181225b8SBruno Cardoso Lopes     collectHeaderMaps(PP->getHeaderSearchInfo(), ModuleDepCollector);
5167aff2bb3SBruno Cardoso Lopes     collectIncludePCH(*this, ModuleDepCollector);
51782ec4fdeSBruno Cardoso Lopes     collectVFSEntries(*this, ModuleDepCollector);
518181225b8SBruno Cardoso Lopes   }
519b1631d91SBruno Cardoso Lopes 
520b1631d91SBruno Cardoso Lopes   for (auto &Listener : DependencyCollectors)
521b1631d91SBruno Cardoso Lopes     Listener->attachToPreprocessor(*PP);
522aaa148fdSDaniel Dunbar 
52327734fdbSDaniel Dunbar   // Handle generating header include information, if requested.
52427734fdbSDaniel Dunbar   if (DepOpts.ShowHeaderIncludes)
525f54146c1SNico Weber     AttachHeaderIncludeGen(*PP, DepOpts);
5261af1d275SDaniel Dunbar   if (!DepOpts.HeaderIncludeOutputFile.empty()) {
5270e62c1ccSChris Lattner     StringRef OutputPath = DepOpts.HeaderIncludeOutputFile;
5281af1d275SDaniel Dunbar     if (OutputPath == "-")
5291af1d275SDaniel Dunbar       OutputPath = "";
530f54146c1SNico Weber     AttachHeaderIncludeGen(*PP, DepOpts,
5311193f2cbSIvan Krasin                            /*ShowAllHeaders=*/true, OutputPath,
532fe908a80SDaniel Dunbar                            /*ShowDepth=*/false);
5330fd6207dSHans Wennborg   }
5340fd6207dSHans Wennborg 
535425f48d4SErich Keane   if (DepOpts.ShowIncludesDest != ShowIncludesDestination::None) {
536f54146c1SNico Weber     AttachHeaderIncludeGen(*PP, DepOpts,
537149d9522SNico Weber                            /*ShowAllHeaders=*/true, /*OutputPath=*/"",
5380fd6207dSHans Wennborg                            /*ShowDepth=*/true, /*MSStyle=*/true);
5391af1d275SDaniel Dunbar   }
540aaa148fdSDaniel Dunbar }
541df3e30c4SDaniel Dunbar 
getSpecificModuleCachePath(StringRef ModuleHash)54258c586e7SAlexandre Rames std::string CompilerInstance::getSpecificModuleCachePath(StringRef ModuleHash) {
54358c586e7SAlexandre Rames   // Set up the module path, including the hash for the module-creation options.
544d520a250SRichard Smith   SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath);
545d520a250SRichard Smith   if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash)
54658c586e7SAlexandre Rames     llvm::sys::path::append(SpecificModuleCache, ModuleHash);
547adcd0268SBenjamin Kramer   return std::string(SpecificModuleCache.str());
548bd0b651bSArgyrios Kyrtzidis }
549bd0b651bSArgyrios Kyrtzidis 
550df3e30c4SDaniel Dunbar // ASTContext
551df3e30c4SDaniel Dunbar 
createASTContext()552df3e30c4SDaniel Dunbar void CompilerInstance::createASTContext() {
553df3e30c4SDaniel Dunbar   Preprocessor &PP = getPreprocessor();
554293534b1SRichard Smith   auto *Context = new ASTContext(getLangOpts(), PP.getSourceManager(),
55508043437SAlp Toker                                  PP.getIdentifierTable(), PP.getSelectorTable(),
55611b47c10SVassil Vassilev                                  PP.getBuiltinInfo(), PP.TUKind);
557b5bc923aSArtem Belevich   Context->InitBuiltinTypes(getTarget(), getAuxTarget());
558293534b1SRichard Smith   setASTContext(Context);
559df3e30c4SDaniel Dunbar }
560599313efSDaniel Dunbar 
561599313efSDaniel Dunbar // ExternalASTSource
562599313efSDaniel Dunbar 
563aae776a5SJan Svoboda namespace {
564aae776a5SJan Svoboda // Helper to recursively read the module names for all modules we're adding.
565aae776a5SJan Svoboda // We mark these as known and redirect any attempt to load that module to
566aae776a5SJan Svoboda // the files we were handed.
567aae776a5SJan Svoboda struct ReadModuleNames : ASTReaderListener {
56808c8016cSJan Svoboda   Preprocessor &PP;
569a2d805c0SJan Svoboda   llvm::SmallVector<std::string, 8> LoadedModules;
570aae776a5SJan Svoboda 
ReadModuleNames__anon95e63fe90111::ReadModuleNames57108c8016cSJan Svoboda   ReadModuleNames(Preprocessor &PP) : PP(PP) {}
572aae776a5SJan Svoboda 
ReadModuleName__anon95e63fe90111::ReadModuleNames573aae776a5SJan Svoboda   void ReadModuleName(StringRef ModuleName) override {
574a2d805c0SJan Svoboda     // Keep the module name as a string for now. It's not safe to create a new
575a2d805c0SJan Svoboda     // IdentifierInfo from an ASTReader callback.
576a2d805c0SJan Svoboda     LoadedModules.push_back(ModuleName.str());
577aae776a5SJan Svoboda   }
578aae776a5SJan Svoboda 
registerAll__anon95e63fe90111::ReadModuleNames579aae776a5SJan Svoboda   void registerAll() {
58008c8016cSJan Svoboda     ModuleMap &MM = PP.getHeaderSearchInfo().getModuleMap();
581a2d805c0SJan Svoboda     for (const std::string &LoadedModule : LoadedModules)
582a2d805c0SJan Svoboda       MM.cacheModuleLoad(*PP.getIdentifierInfo(LoadedModule),
583a2d805c0SJan Svoboda                          MM.findModule(LoadedModule));
584aae776a5SJan Svoboda     LoadedModules.clear();
585aae776a5SJan Svoboda   }
586aae776a5SJan Svoboda 
markAllUnavailable__anon95e63fe90111::ReadModuleNames587aae776a5SJan Svoboda   void markAllUnavailable() {
588a2d805c0SJan Svoboda     for (const std::string &LoadedModule : LoadedModules) {
58908c8016cSJan Svoboda       if (Module *M = PP.getHeaderSearchInfo().getModuleMap().findModule(
590a2d805c0SJan Svoboda               LoadedModule)) {
591aae776a5SJan Svoboda         M->HasIncompatibleModuleFile = true;
592aae776a5SJan Svoboda 
593aae776a5SJan Svoboda         // Mark module as available if the only reason it was unavailable
594aae776a5SJan Svoboda         // was missing headers.
595aae776a5SJan Svoboda         SmallVector<Module *, 2> Stack;
596aae776a5SJan Svoboda         Stack.push_back(M);
597aae776a5SJan Svoboda         while (!Stack.empty()) {
598aae776a5SJan Svoboda           Module *Current = Stack.pop_back_val();
599aae776a5SJan Svoboda           if (Current->IsUnimportable) continue;
600aae776a5SJan Svoboda           Current->IsAvailable = true;
601aae776a5SJan Svoboda           Stack.insert(Stack.end(),
602aae776a5SJan Svoboda                        Current->submodule_begin(), Current->submodule_end());
603aae776a5SJan Svoboda         }
604aae776a5SJan Svoboda       }
605aae776a5SJan Svoboda     }
606aae776a5SJan Svoboda     LoadedModules.clear();
607aae776a5SJan Svoboda   }
608aae776a5SJan Svoboda };
609aae776a5SJan Svoboda } // namespace
610aae776a5SJan Svoboda 
createPCHExternalASTSource(StringRef Path,DisableValidationForModuleKind DisableValidation,bool AllowPCHWithCompilerErrors,void * DeserializationListener,bool OwnDeserializationListener)611824285ecSNico Weber void CompilerInstance::createPCHExternalASTSource(
612b0e89906SArgyrios Kyrtzidis     StringRef Path, DisableValidationForModuleKind DisableValidation,
613b0e89906SArgyrios Kyrtzidis     bool AllowPCHWithCompilerErrors, void *DeserializationListener,
614b0e89906SArgyrios Kyrtzidis     bool OwnDeserializationListener) {
615009e7f20SSebastian Redl   bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
61620d51b2fSDuncan P. N. Exon Smith   TheASTReader = createPCHExternalASTSource(
617b0e89906SArgyrios Kyrtzidis       Path, getHeaderSearchOpts().Sysroot, DisableValidation,
6188bef5cd4SDuncan P. N. Exon Smith       AllowPCHWithCompilerErrors, getPreprocessor(), getModuleCache(),
6198bef5cd4SDuncan P. N. Exon Smith       getASTContext(), getPCHContainerReader(),
6208d9eb7acSAlex Lorenz       getFrontendOpts().ModuleFileExtensions, DependencyCollectors,
6218d9eb7acSAlex Lorenz       DeserializationListener, OwnDeserializationListener, Preamble,
6228d9eb7acSAlex Lorenz       getFrontendOpts().UseGlobalModuleIndex);
623599313efSDaniel Dunbar }
624599313efSDaniel Dunbar 
createPCHExternalASTSource(StringRef Path,StringRef Sysroot,DisableValidationForModuleKind DisableValidation,bool AllowPCHWithCompilerErrors,Preprocessor & PP,InMemoryModuleCache & ModuleCache,ASTContext & Context,const PCHContainerReader & PCHContainerRdr,ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,void * DeserializationListener,bool OwnDeserializationListener,bool Preamble,bool UseGlobalModuleIndex)6254eca9b93SRichard Smith IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
626b0e89906SArgyrios Kyrtzidis     StringRef Path, StringRef Sysroot,
627b0e89906SArgyrios Kyrtzidis     DisableValidationForModuleKind DisableValidation,
6288bef5cd4SDuncan P. N. Exon Smith     bool AllowPCHWithCompilerErrors, Preprocessor &PP,
6298bef5cd4SDuncan P. N. Exon Smith     InMemoryModuleCache &ModuleCache, ASTContext &Context,
630fb2398d0SAdrian Prantl     const PCHContainerReader &PCHContainerRdr,
63161137e1aSDavid Blaikie     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
632ce539b54SGraydon Hoare     ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
633824285ecSNico Weber     void *DeserializationListener, bool OwnDeserializationListener,
634824285ecSNico Weber     bool Preamble, bool UseGlobalModuleIndex) {
635dcf73861SBen Langmuir   HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
636dcf73861SBen Langmuir 
637bb165fb0SAdrian Prantl   IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(
6388bef5cd4SDuncan P. N. Exon Smith       PP, ModuleCache, &Context, PCHContainerRdr, Extensions,
639b0e89906SArgyrios Kyrtzidis       Sysroot.empty() ? "" : Sysroot.data(), DisableValidation,
6406623e1f1SDouglas Gregor       AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false,
6411731fc88SBruno Cardoso Lopes       HSOpts.ModulesValidateSystemHeaders, HSOpts.ValidateASTInputFilesContent,
6421731fc88SBruno Cardoso Lopes       UseGlobalModuleIndex));
6434eca9b93SRichard Smith 
6444eca9b93SRichard Smith   // We need the external source to be set up before we read the AST, because
6454eca9b93SRichard Smith   // eagerly-deserialized declarations may use it.
6464eca9b93SRichard Smith   Context.setExternalSource(Reader.get());
647599313efSDaniel Dunbar 
64807a89a83SSebastian Redl   Reader->setDeserializationListener(
649824285ecSNico Weber       static_cast<ASTDeserializationListener *>(DeserializationListener),
650824285ecSNico Weber       /*TakeOwnership=*/OwnDeserializationListener);
651ce539b54SGraydon Hoare 
652ce539b54SGraydon Hoare   for (auto &Listener : DependencyCollectors)
653ce539b54SGraydon Hoare     Listener->attachToASTReader(*Reader);
654ce539b54SGraydon Hoare 
65508c8016cSJan Svoboda   auto Listener = std::make_unique<ReadModuleNames>(PP);
65608c8016cSJan Svoboda   auto &ListenerRef = *Listener;
65708c8016cSJan Svoboda   ASTReader::ListenerScope ReadModuleNamesListener(*Reader,
65808c8016cSJan Svoboda                                                    std::move(Listener));
65908c8016cSJan Svoboda 
660009e7f20SSebastian Redl   switch (Reader->ReadAST(Path,
661a6895d8aSDouglas Gregor                           Preamble ? serialization::MK_Preamble
6624b29c16eSDouglas Gregor                                    : serialization::MK_PCH,
6632ec29367SArgyrios Kyrtzidis                           SourceLocation(),
6643d4417c7SBen Langmuir                           ASTReader::ARR_None)) {
6652c499f65SSebastian Redl   case ASTReader::Success:
666599313efSDaniel Dunbar     // Set the predefines buffer as suggested by the PCH reader. Typically, the
667599313efSDaniel Dunbar     // predefines buffer will be empty.
668599313efSDaniel Dunbar     PP.setPredefines(Reader->getSuggestedPredefines());
66908c8016cSJan Svoboda     ListenerRef.registerAll();
6704eca9b93SRichard Smith     return Reader;
671599313efSDaniel Dunbar 
6722c499f65SSebastian Redl   case ASTReader::Failure:
673599313efSDaniel Dunbar     // Unrecoverable failure: don't even try to process the input file.
674599313efSDaniel Dunbar     break;
675599313efSDaniel Dunbar 
6767029ce1aSDouglas Gregor   case ASTReader::Missing:
677c9ad5fb6SDouglas Gregor   case ASTReader::OutOfDate:
678c9ad5fb6SDouglas Gregor   case ASTReader::VersionMismatch:
679c9ad5fb6SDouglas Gregor   case ASTReader::ConfigurationMismatch:
680c9ad5fb6SDouglas Gregor   case ASTReader::HadErrors:
681599313efSDaniel Dunbar     // No suitable PCH file could be found. Return an error.
682599313efSDaniel Dunbar     break;
683599313efSDaniel Dunbar   }
684599313efSDaniel Dunbar 
68508c8016cSJan Svoboda   ListenerRef.markAllUnavailable();
6864eca9b93SRichard Smith   Context.setExternalSource(nullptr);
68749a2790fSCraig Topper   return nullptr;
688599313efSDaniel Dunbar }
689f7093b5aSDaniel Dunbar 
690f7093b5aSDaniel Dunbar // Code Completion
691f7093b5aSDaniel Dunbar 
EnableCodeCompletion(Preprocessor & PP,StringRef Filename,unsigned Line,unsigned Column)6928e984da8SDouglas Gregor static bool EnableCodeCompletion(Preprocessor &PP,
6930772c423SBenjamin Kramer                                  StringRef Filename,
6948e984da8SDouglas Gregor                                  unsigned Line,
6958e984da8SDouglas Gregor                                  unsigned Column) {
6968e984da8SDouglas Gregor   // Tell the source manager to chop off the given file at a specific
6978e984da8SDouglas Gregor   // line and column.
6988d323d15SHarlan Haskins   auto Entry = PP.getFileManager().getFile(Filename);
6998e984da8SDouglas Gregor   if (!Entry) {
7008e984da8SDouglas Gregor     PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
7018e984da8SDouglas Gregor       << Filename;
7028e984da8SDouglas Gregor     return true;
7038e984da8SDouglas Gregor   }
7048e984da8SDouglas Gregor 
7058e984da8SDouglas Gregor   // Truncate the named file at the given line/column.
7068d323d15SHarlan Haskins   PP.SetCodeCompletionPoint(*Entry, Line, Column);
7078e984da8SDouglas Gregor   return false;
7088e984da8SDouglas Gregor }
7098e984da8SDouglas Gregor 
createCodeCompletionConsumer()710f7093b5aSDaniel Dunbar void CompilerInstance::createCodeCompletionConsumer() {
711f7093b5aSDaniel Dunbar   const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt;
7128e984da8SDouglas Gregor   if (!CompletionConsumer) {
713d3d3e252SYuki Okushi     setCodeCompletionConsumer(createCodeCompletionConsumer(
714d3d3e252SYuki Okushi         getPreprocessor(), Loc.FileName, Loc.Line, Loc.Column,
715d3d3e252SYuki Okushi         getFrontendOpts().CodeCompleteOpts, llvm::outs()));
71600a0cf70SDouglas Gregor     return;
7178e984da8SDouglas Gregor   } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName,
7188e984da8SDouglas Gregor                                   Loc.Line, Loc.Column)) {
71949a2790fSCraig Topper     setCodeCompletionConsumer(nullptr);
7208e984da8SDouglas Gregor     return;
7218e984da8SDouglas Gregor   }
722f7093b5aSDaniel Dunbar }
723f7093b5aSDaniel Dunbar 
createFrontendTimer()7245505dff8SKovarththanan Rajaratnam void CompilerInstance::createFrontendTimer() {
725ae032b6cSMatthias Braun   FrontendTimerGroup.reset(
726ae032b6cSMatthias Braun       new llvm::TimerGroup("frontend", "Clang front-end time report"));
727ce18a187SRichard Smith   FrontendTimer.reset(
728ae032b6cSMatthias Braun       new llvm::Timer("frontend", "Clang front-end timer",
729ae032b6cSMatthias Braun                       *FrontendTimerGroup));
7305505dff8SKovarththanan Rajaratnam }
7315505dff8SKovarththanan Rajaratnam 
732f7093b5aSDaniel Dunbar CodeCompleteConsumer *
createCodeCompletionConsumer(Preprocessor & PP,StringRef Filename,unsigned Line,unsigned Column,const CodeCompleteOptions & Opts,raw_ostream & OS)733f7093b5aSDaniel Dunbar CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP,
7345b816061SYaron Keren                                                StringRef Filename,
735f7093b5aSDaniel Dunbar                                                unsigned Line,
736f7093b5aSDaniel Dunbar                                                unsigned Column,
7373292d06aSDmitri Gribenko                                                const CodeCompleteOptions &Opts,
7380e62c1ccSChris Lattner                                                raw_ostream &OS) {
7398e984da8SDouglas Gregor   if (EnableCodeCompletion(PP, Filename, Line, Column))
74049a2790fSCraig Topper     return nullptr;
741f7093b5aSDaniel Dunbar 
742f7093b5aSDaniel Dunbar   // Set up the creation routine for code-completion.
7433292d06aSDmitri Gribenko   return new PrintingCodeCompleteConsumer(Opts, OS);
744f7093b5aSDaniel Dunbar }
745566eeb2dSDaniel Dunbar 
createSema(TranslationUnitKind TUKind,CodeCompleteConsumer * CompletionConsumer)74669f74f80SDouglas Gregor void CompilerInstance::createSema(TranslationUnitKind TUKind,
7470e93f017SDouglas Gregor                                   CodeCompleteConsumer *CompletionConsumer) {
7480e93f017SDouglas Gregor   TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(),
74969f74f80SDouglas Gregor                          TUKind, CompletionConsumer));
7507de9969bSBenjamin Kramer   // Attach the external sema source if there is any.
7517de9969bSBenjamin Kramer   if (ExternalSemaSrc) {
7527de9969bSBenjamin Kramer     TheSema->addExternalSource(ExternalSemaSrc.get());
7537de9969bSBenjamin Kramer     ExternalSemaSrc->InitializeSema(*TheSema);
7547de9969bSBenjamin Kramer   }
7550e93f017SDouglas Gregor }
7560e93f017SDouglas Gregor 
757566eeb2dSDaniel Dunbar // Output Files
758566eeb2dSDaniel Dunbar 
clearOutputFiles(bool EraseFiles)7591c558cd7SKovarththanan Rajaratnam void CompilerInstance::clearOutputFiles(bool EraseFiles) {
76067a84ec8SBen Langmuir   // The ASTConsumer can own streams that write to the output files.
76167a84ec8SBen Langmuir   assert(!hasASTConsumer() && "ASTConsumer should be reset");
7629d070b2fSAmy Huang   // Ignore errors that occur when trying to discard the temp file.
7630aa128e2SReid Kleckner   for (OutputFile &OF : OutputFiles) {
764b5c356a4SAnders Carlsson     if (EraseFiles) {
7659d070b2fSAmy Huang       if (OF.File)
7669d070b2fSAmy Huang         consumeError(OF.File->discard());
7678e464dd7SDuncan P. N. Exon Smith       if (!OF.Filename.empty())
7688e464dd7SDuncan P. N. Exon Smith         llvm::sys::fs::remove(OF.Filename);
7698e464dd7SDuncan P. N. Exon Smith       continue;
7708e464dd7SDuncan P. N. Exon Smith     }
7718e464dd7SDuncan P. N. Exon Smith 
7729d070b2fSAmy Huang     if (!OF.File)
7738e464dd7SDuncan P. N. Exon Smith       continue;
774b5c356a4SAnders Carlsson 
7759d070b2fSAmy Huang     if (OF.File->TmpName.empty()) {
7769d070b2fSAmy Huang       consumeError(OF.File->discard());
7779d070b2fSAmy Huang       continue;
7789d070b2fSAmy Huang     }
7799d070b2fSAmy Huang 
78071731d6bSArgyrios Kyrtzidis     // If '-working-directory' was passed, the output filename should be
78171731d6bSArgyrios Kyrtzidis     // relative to that.
7828e464dd7SDuncan P. N. Exon Smith     SmallString<128> NewOutFile(OF.Filename);
7839ba8fb1eSAnders Carlsson     FileMgr->FixupRelativePath(NewOutFile);
7847daa1821SAmy Huang 
7859d070b2fSAmy Huang     llvm::Error E = OF.File->keep(NewOutFile);
7869d070b2fSAmy Huang     if (!E)
7879d070b2fSAmy Huang       continue;
7889d070b2fSAmy Huang 
7899d070b2fSAmy Huang     getDiagnostics().Report(diag::err_unable_to_rename_temp)
7909d070b2fSAmy Huang         << OF.File->TmpName << OF.Filename << std::move(E);
7919d070b2fSAmy Huang 
7929d070b2fSAmy Huang     llvm::sys::fs::remove(OF.File->TmpName);
793d0599970SArgyrios Kyrtzidis   }
794566eeb2dSDaniel Dunbar   OutputFiles.clear();
79586a3ef5bSRichard Smith   if (DeleteBuiltModules) {
7965d2ed489SRichard Smith     for (auto &Module : BuiltModules)
7975d2ed489SRichard Smith       llvm::sys::fs::remove(Module.second);
79886a3ef5bSRichard Smith     BuiltModules.clear();
79986a3ef5bSRichard Smith   }
800566eeb2dSDaniel Dunbar }
801566eeb2dSDaniel Dunbar 
createDefaultOutputFile(bool Binary,StringRef InFile,StringRef Extension,bool RemoveFileOnSignal,bool CreateMissingDirectories,bool ForceUseTemporary)80205d0f1a8SZachary Henkel std::unique_ptr<raw_pwrite_stream> CompilerInstance::createDefaultOutputFile(
80305d0f1a8SZachary Henkel     bool Binary, StringRef InFile, StringRef Extension, bool RemoveFileOnSignal,
80405d0f1a8SZachary Henkel     bool CreateMissingDirectories, bool ForceUseTemporary) {
805ad7aaa47SDuncan P. N. Exon Smith   StringRef OutputPath = getFrontendOpts().OutputFile;
806ad7aaa47SDuncan P. N. Exon Smith   Optional<SmallString<128>> PathStorage;
807ad7aaa47SDuncan P. N. Exon Smith   if (OutputPath.empty()) {
808ad7aaa47SDuncan P. N. Exon Smith     if (InFile == "-" || Extension.empty()) {
809ad7aaa47SDuncan P. N. Exon Smith       OutputPath = "-";
810ad7aaa47SDuncan P. N. Exon Smith     } else {
811ad7aaa47SDuncan P. N. Exon Smith       PathStorage.emplace(InFile);
812ad7aaa47SDuncan P. N. Exon Smith       llvm::sys::path::replace_extension(*PathStorage, Extension);
813ad7aaa47SDuncan P. N. Exon Smith       OutputPath = *PathStorage;
814ad7aaa47SDuncan P. N. Exon Smith     }
815ad7aaa47SDuncan P. N. Exon Smith   }
816ad7aaa47SDuncan P. N. Exon Smith 
817ad7aaa47SDuncan P. N. Exon Smith   return createOutputFile(OutputPath, Binary, RemoveFileOnSignal,
81805d0f1a8SZachary Henkel                           getFrontendOpts().UseTemporary || ForceUseTemporary,
819ad7aaa47SDuncan P. N. Exon Smith                           CreateMissingDirectories);
820420b0f1bSDaniel Dunbar }
821420b0f1bSDaniel Dunbar 
createNullOutputFile()82203f8907fSPeter Collingbourne std::unique_ptr<raw_pwrite_stream> CompilerInstance::createNullOutputFile() {
8232b3d49b6SJonas Devlieghere   return std::make_unique<llvm::raw_null_ostream>();
824ea04672cSAlp Toker }
825ea04672cSAlp Toker 
82603f8907fSPeter Collingbourne std::unique_ptr<raw_pwrite_stream>
createOutputFile(StringRef OutputPath,bool Binary,bool RemoveFileOnSignal,bool UseTemporary,bool CreateMissingDirectories)8272f16bc10SRafael Espindola CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary,
828ad7aaa47SDuncan P. N. Exon Smith                                    bool RemoveFileOnSignal, bool UseTemporary,
829b9c62c07SDaniel Dunbar                                    bool CreateMissingDirectories) {
830ad7aaa47SDuncan P. N. Exon Smith   Expected<std::unique_ptr<raw_pwrite_stream>> OS =
831ad7aaa47SDuncan P. N. Exon Smith       createOutputFileImpl(OutputPath, Binary, RemoveFileOnSignal, UseTemporary,
832ad7aaa47SDuncan P. N. Exon Smith                            CreateMissingDirectories);
833ad7aaa47SDuncan P. N. Exon Smith   if (OS)
834ad7aaa47SDuncan P. N. Exon Smith     return std::move(*OS);
835ad7aaa47SDuncan P. N. Exon Smith   getDiagnostics().Report(diag::err_fe_unable_to_open_output)
836ad7aaa47SDuncan P. N. Exon Smith       << OutputPath << errorToErrorCode(OS.takeError()).message();
83749a2790fSCraig Topper   return nullptr;
838420b0f1bSDaniel Dunbar }
839420b0f1bSDaniel Dunbar 
840ad7aaa47SDuncan P. N. Exon Smith Expected<std::unique_ptr<llvm::raw_pwrite_stream>>
createOutputFileImpl(StringRef OutputPath,bool Binary,bool RemoveFileOnSignal,bool UseTemporary,bool CreateMissingDirectories)841ad7aaa47SDuncan P. N. Exon Smith CompilerInstance::createOutputFileImpl(StringRef OutputPath, bool Binary,
842ad7aaa47SDuncan P. N. Exon Smith                                        bool RemoveFileOnSignal,
843ad7aaa47SDuncan P. N. Exon Smith                                        bool UseTemporary,
844ad7aaa47SDuncan P. N. Exon Smith                                        bool CreateMissingDirectories) {
845b9c62c07SDaniel Dunbar   assert((!CreateMissingDirectories || UseTemporary) &&
846b9c62c07SDaniel Dunbar          "CreateMissingDirectories is only allowed when using temporary files");
847b9c62c07SDaniel Dunbar 
848b8984329SAhmed Charles   std::unique_ptr<llvm::raw_fd_ostream> OS;
849ad7aaa47SDuncan P. N. Exon Smith   Optional<StringRef> OSFile;
85008a2bfd2SArgyrios Kyrtzidis 
85173c23a71SRafael Espindola   if (UseTemporary) {
852ad7aaa47SDuncan P. N. Exon Smith     if (OutputPath == "-")
85373c23a71SRafael Espindola       UseTemporary = false;
85473c23a71SRafael Espindola     else {
85573c23a71SRafael Espindola       llvm::sys::fs::file_status Status;
85673c23a71SRafael Espindola       llvm::sys::fs::status(OutputPath, Status);
85773c23a71SRafael Espindola       if (llvm::sys::fs::exists(Status)) {
85873c23a71SRafael Espindola         // Fail early if we can't write to the final destination.
859ad7aaa47SDuncan P. N. Exon Smith         if (!llvm::sys::fs::can_write(OutputPath))
860ad7aaa47SDuncan P. N. Exon Smith           return llvm::errorCodeToError(
861ad7aaa47SDuncan P. N. Exon Smith               make_error_code(llvm::errc::operation_not_permitted));
86273c23a71SRafael Espindola 
86373c23a71SRafael Espindola         // Don't use a temporary if the output is a special file. This handles
86473c23a71SRafael Espindola         // things like '-o /dev/null'
86573c23a71SRafael Espindola         if (!llvm::sys::fs::is_regular_file(Status))
86673c23a71SRafael Espindola           UseTemporary = false;
86773c23a71SRafael Espindola       }
86873c23a71SRafael Espindola     }
86973c23a71SRafael Espindola   }
87073c23a71SRafael Espindola 
8719d070b2fSAmy Huang   Optional<llvm::sys::fs::TempFile> Temp;
87273c23a71SRafael Espindola   if (UseTemporary) {
873d0599970SArgyrios Kyrtzidis     // Create a temporary file.
8742db47198SNico Weber     // Insert -%%%%%%%% before the extension (if any), and because some tools
8752db47198SNico Weber     // (noticeable, clang's own GlobalModuleIndex.cpp) glob for build
8762db47198SNico Weber     // artifacts, also append .tmp.
877ad7aaa47SDuncan P. N. Exon Smith     StringRef OutputExtension = llvm::sys::path::extension(OutputPath);
8782db47198SNico Weber     SmallString<128> TempPath =
879ad7aaa47SDuncan P. N. Exon Smith         StringRef(OutputPath).drop_back(OutputExtension.size());
88008a2bfd2SArgyrios Kyrtzidis     TempPath += "-%%%%%%%%";
8812db47198SNico Weber     TempPath += OutputExtension;
8822db47198SNico Weber     TempPath += ".tmp";
8839d070b2fSAmy Huang     Expected<llvm::sys::fs::TempFile> ExpectedFile =
8840e8506deSAbhina Sreeskantharajan         llvm::sys::fs::TempFile::create(
8850e8506deSAbhina Sreeskantharajan             TempPath, llvm::sys::fs::all_read | llvm::sys::fs::all_write,
8860e8506deSAbhina Sreeskantharajan             Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_Text);
887157f34bdSRafael Espindola 
8889d070b2fSAmy Huang     llvm::Error E = handleErrors(
8899d070b2fSAmy Huang         ExpectedFile.takeError(), [&](const llvm::ECError &E) -> llvm::Error {
8909d070b2fSAmy Huang           std::error_code EC = E.convertToErrorCode();
891157f34bdSRafael Espindola           if (CreateMissingDirectories &&
89271de0b61SRafael Espindola               EC == llvm::errc::no_such_file_or_directory) {
893157f34bdSRafael Espindola             StringRef Parent = llvm::sys::path::parent_path(OutputPath);
894157f34bdSRafael Espindola             EC = llvm::sys::fs::create_directories(Parent);
895157f34bdSRafael Espindola             if (!EC) {
8969d070b2fSAmy Huang               ExpectedFile = llvm::sys::fs::TempFile::create(TempPath);
8979d070b2fSAmy Huang               if (!ExpectedFile)
8989d070b2fSAmy Huang                 return llvm::errorCodeToError(
8999d070b2fSAmy Huang                     llvm::errc::no_such_file_or_directory);
90020797b12SAmy Huang             }
90120797b12SAmy Huang           }
9029d070b2fSAmy Huang           return llvm::errorCodeToError(EC);
9039d070b2fSAmy Huang         });
90420797b12SAmy Huang 
9059d070b2fSAmy Huang     if (E) {
9069d070b2fSAmy Huang       consumeError(std::move(E));
9079d070b2fSAmy Huang     } else {
9089d070b2fSAmy Huang       Temp = std::move(ExpectedFile.get());
909cf11d958SAmy Huang       OS.reset(new llvm::raw_fd_ostream(Temp->FD, /*shouldClose=*/false));
9109d070b2fSAmy Huang       OSFile = Temp->TmpName;
91108a2bfd2SArgyrios Kyrtzidis     }
91273c23a71SRafael Espindola     // If we failed to create the temporary, fallback to writing to the file
91373c23a71SRafael Espindola     // directly. This handles the corner case where we cannot write to the
91473c23a71SRafael Espindola     // directory, but can write to the file.
915d0599970SArgyrios Kyrtzidis   }
916d0599970SArgyrios Kyrtzidis 
91708a2bfd2SArgyrios Kyrtzidis   if (!OS) {
918ad7aaa47SDuncan P. N. Exon Smith     OSFile = OutputPath;
919ad7aaa47SDuncan P. N. Exon Smith     std::error_code EC;
92069f3528cSNAKAMURA Takumi     OS.reset(new llvm::raw_fd_ostream(
921ad7aaa47SDuncan P. N. Exon Smith         *OSFile, EC,
92282b3e28eSAbhina Sreeskantharajan         (Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_TextWithCRLF)));
923ad7aaa47SDuncan P. N. Exon Smith     if (EC)
924ad7aaa47SDuncan P. N. Exon Smith       return llvm::errorCodeToError(EC);
92508a2bfd2SArgyrios Kyrtzidis   }
926420b0f1bSDaniel Dunbar 
927ad7aaa47SDuncan P. N. Exon Smith   // Add the output file -- but don't try to remove "-", since this means we are
928ad7aaa47SDuncan P. N. Exon Smith   // using stdin.
929ad7aaa47SDuncan P. N. Exon Smith   OutputFiles.emplace_back(((OutputPath != "-") ? OutputPath : "").str(),
9309d070b2fSAmy Huang                            std::move(Temp));
931420b0f1bSDaniel Dunbar 
9322f16bc10SRafael Espindola   if (!Binary || OS->supportsSeeking())
9332f16bc10SRafael Espindola     return std::move(OS);
9342f16bc10SRafael Espindola 
9352f721476SDuncan P. N. Exon Smith   return std::make_unique<llvm::buffer_unique_ostream>(std::move(OS));
936420b0f1bSDaniel Dunbar }
937409e890fSDaniel Dunbar 
938409e890fSDaniel Dunbar // Initialization Utilities
939409e890fSDaniel Dunbar 
InitializeSourceManager(const FrontendInputFile & Input)9401b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){
941ef875c22SAndrzej Warzynski   return InitializeSourceManager(Input, getDiagnostics(), getFileManager(),
942ef875c22SAndrzej Warzynski                                  getSourceManager());
943409e890fSDaniel Dunbar }
944409e890fSDaniel Dunbar 
9452ca4be97SNico Weber // static
InitializeSourceManager(const FrontendInputFile & Input,DiagnosticsEngine & Diags,FileManager & FileMgr,SourceManager & SourceMgr)946ef875c22SAndrzej Warzynski bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input,
947ef875c22SAndrzej Warzynski                                                DiagnosticsEngine &Diags,
948ef875c22SAndrzej Warzynski                                                FileManager &FileMgr,
949ef875c22SAndrzej Warzynski                                                SourceManager &SourceMgr) {
950f3f84616SRichard Smith   SrcMgr::CharacteristicKind Kind =
951f3f84616SRichard Smith       Input.getKind().getFormat() == InputKind::ModuleMap
952f3f84616SRichard Smith           ? Input.isSystem() ? SrcMgr::C_System_ModuleMap
953f3f84616SRichard Smith                              : SrcMgr::C_User_ModuleMap
954f3f84616SRichard Smith           : Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
9551b3240b0SArgyrios Kyrtzidis 
9566566e23eSArgyrios Kyrtzidis   if (Input.isBuffer()) {
95751d1d585SDuncan P. N. Exon Smith     SourceMgr.setMainFileID(SourceMgr.createFileID(Input.getBuffer(), Kind));
9588b563665SYaron Keren     assert(SourceMgr.getMainFileID().isValid() &&
9596566e23eSArgyrios Kyrtzidis            "Couldn't establish MainFileID!");
9606566e23eSArgyrios Kyrtzidis     return true;
9616566e23eSArgyrios Kyrtzidis   }
9626566e23eSArgyrios Kyrtzidis 
9636566e23eSArgyrios Kyrtzidis   StringRef InputFile = Input.getFile();
9646566e23eSArgyrios Kyrtzidis 
9657c06d866SArgyrios Kyrtzidis   // Figure out where to get and map in the main file.
9663ee43adfSDuncan P. N. Exon Smith   auto FileOrErr = InputFile == "-"
9673ee43adfSDuncan P. N. Exon Smith                        ? FileMgr.getSTDIN()
9683ee43adfSDuncan P. N. Exon Smith                        : FileMgr.getFileRef(InputFile, /*OpenFile=*/true);
9698d323d15SHarlan Haskins   if (!FileOrErr) {
9703ee43adfSDuncan P. N. Exon Smith     // FIXME: include the error in the diagnostic even when it's not stdin.
9713ee43adfSDuncan P. N. Exon Smith     auto EC = llvm::errorToErrorCode(FileOrErr.takeError());
9723ee43adfSDuncan P. N. Exon Smith     if (InputFile != "-")
973409e890fSDaniel Dunbar       Diags.Report(diag::err_fe_error_reading) << InputFile;
9743ee43adfSDuncan P. N. Exon Smith     else
9753ee43adfSDuncan P. N. Exon Smith       Diags.Report(diag::err_fe_error_reading_stdin) << EC.message();
976409e890fSDaniel Dunbar     return false;
977409e890fSDaniel Dunbar   }
978e2951f48SDaniel Dunbar 
979b3463220SDuncan P. N. Exon Smith   SourceMgr.setMainFileID(
980245218bbSDuncan P. N. Exon Smith       SourceMgr.createFileID(*FileOrErr, SourceLocation(), Kind));
981409e890fSDaniel Dunbar 
9828b563665SYaron Keren   assert(SourceMgr.getMainFileID().isValid() &&
98352765215SDan Gohman          "Couldn't establish MainFileID!");
984409e890fSDaniel Dunbar   return true;
985409e890fSDaniel Dunbar }
9864f2bc55dSDaniel Dunbar 
9874f2bc55dSDaniel Dunbar // High-Level Operations
9884f2bc55dSDaniel Dunbar 
ExecuteAction(FrontendAction & Act)9894f2bc55dSDaniel Dunbar bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
9904f2bc55dSDaniel Dunbar   assert(hasDiagnostics() && "Diagnostics engine is not initialized!");
9914f2bc55dSDaniel Dunbar   assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!");
9924f2bc55dSDaniel Dunbar   assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!");
9934f2bc55dSDaniel Dunbar 
99426a92d58SRichard Smith   // Mark this point as the bottom of the stack if we don't have somewhere
99526a92d58SRichard Smith   // better. We generally expect frontend actions to be invoked with (nearly)
99626a92d58SRichard Smith   // DesiredStackSpace available.
99726a92d58SRichard Smith   noteBottomOfStack();
99826a92d58SRichard Smith 
99976cb4cd0SJan Svoboda   auto FinishDiagnosticClient = llvm::make_scope_exit([&]() {
100076cb4cd0SJan Svoboda     // Notify the diagnostic client that all files were processed.
100176cb4cd0SJan Svoboda     getDiagnosticClient().finish();
100276cb4cd0SJan Svoboda   });
100376cb4cd0SJan Svoboda 
100487cb734cSScott Linder   raw_ostream &OS = getVerboseOutputStream();
10054f2bc55dSDaniel Dunbar 
1006d6509cf2SRichard Smith   if (!Act.PrepareToExecute(*this))
1007d6509cf2SRichard Smith     return false;
1008d6509cf2SRichard Smith 
1009d412dbe3SYu-Hsun Chiang   if (!createTarget())
10104f2bc55dSDaniel Dunbar     return false;
10114f2bc55dSDaniel Dunbar 
101229898f45SFariborz Jahanian   // rewriter project will change target built-in bool type from its default.
101329898f45SFariborz Jahanian   if (getFrontendOpts().ProgramAction == frontend::RewriteObjC)
101429898f45SFariborz Jahanian     getTarget().noSignedCharForObjCBool();
101529898f45SFariborz Jahanian 
10164f2bc55dSDaniel Dunbar   // Validate/process some options.
10174f2bc55dSDaniel Dunbar   if (getHeaderSearchOpts().Verbose)
10184f2bc55dSDaniel Dunbar     OS << "clang -cc1 version " CLANG_VERSION_STRING
1019f988d006SAlp Toker        << " based upon " << BACKEND_PACKAGE_STRING
10208188c8a1SSebastian Pop        << " default target " << llvm::sys::getDefaultTargetTriple() << "\n";
10214f2bc55dSDaniel Dunbar 
10221821265dSYuanfang Chen   if (getCodeGenOpts().TimePasses)
10234f2bc55dSDaniel Dunbar     createFrontendTimer();
10244f2bc55dSDaniel Dunbar 
1025abb6eea1SMatthias Braun   if (getFrontendOpts().ShowStats || !getFrontendOpts().StatsFile.empty())
1026ec1c5a20SMatthias Braun     llvm::EnableStatistics(false);
1027171b780cSDouglas Gregor 
10285b60ad68SVedant Kumar   for (const FrontendInputFile &FIF : getFrontendOpts().Inputs) {
1029eeccb30bSTed Kremenek     // Reset the ID tables if we are reusing the SourceManager and parsing
1030eeccb30bSTed Kremenek     // regular files.
1031eeccb30bSTed Kremenek     if (hasSourceManager() && !Act.isModelParsingAction())
10324f2bc55dSDaniel Dunbar       getSourceManager().clearIDTables();
10334f2bc55dSDaniel Dunbar 
10345b60ad68SVedant Kumar     if (Act.BeginSourceFile(*this, FIF)) {
10350e828958SJF Bastien       if (llvm::Error Err = Act.Execute()) {
10360e828958SJF Bastien         consumeError(std::move(Err)); // FIXME this drops errors on the floor.
10370e828958SJF Bastien       }
10384f2bc55dSDaniel Dunbar       Act.EndSourceFile();
10394f2bc55dSDaniel Dunbar     }
10404f2bc55dSDaniel Dunbar   }
10414f2bc55dSDaniel Dunbar 
1042198cb4dfSChris Lattner   if (getDiagnosticOpts().ShowCarets) {
1043c79346a5SArgyrios Kyrtzidis     // We can have multiple diagnostics sharing one diagnostic client.
1044c79346a5SArgyrios Kyrtzidis     // Get the total number of warnings/errors from the client.
1045c79346a5SArgyrios Kyrtzidis     unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings();
1046c79346a5SArgyrios Kyrtzidis     unsigned NumErrors = getDiagnostics().getClient()->getNumErrors();
1047198cb4dfSChris Lattner 
1048198cb4dfSChris Lattner     if (NumWarnings)
1049198cb4dfSChris Lattner       OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s");
1050198cb4dfSChris Lattner     if (NumWarnings && NumErrors)
1051198cb4dfSChris Lattner       OS << " and ";
1052198cb4dfSChris Lattner     if (NumErrors)
1053198cb4dfSChris Lattner       OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s");
105478137ec8SJustin Lebar     if (NumWarnings || NumErrors) {
105578137ec8SJustin Lebar       OS << " generated";
105678137ec8SJustin Lebar       if (getLangOpts().CUDA) {
105778137ec8SJustin Lebar         if (!getLangOpts().CUDAIsDevice) {
105878137ec8SJustin Lebar           OS << " when compiling for host";
105978137ec8SJustin Lebar         } else {
106078137ec8SJustin Lebar           OS << " when compiling for " << getTargetOpts().CPU;
106178137ec8SJustin Lebar         }
106278137ec8SJustin Lebar       }
106378137ec8SJustin Lebar       OS << ".\n";
106478137ec8SJustin Lebar     }
1065198cb4dfSChris Lattner   }
10664f2bc55dSDaniel Dunbar 
1067abb6eea1SMatthias Braun   if (getFrontendOpts().ShowStats) {
1068abb6eea1SMatthias Braun     if (hasFileManager()) {
10694f2bc55dSDaniel Dunbar       getFileManager().PrintStats();
1070abb6eea1SMatthias Braun       OS << '\n';
1071abb6eea1SMatthias Braun     }
1072abb6eea1SMatthias Braun     llvm::PrintStatistics(OS);
1073abb6eea1SMatthias Braun   }
1074abb6eea1SMatthias Braun   StringRef StatsFile = getFrontendOpts().StatsFile;
1075abb6eea1SMatthias Braun   if (!StatsFile.empty()) {
1076abb6eea1SMatthias Braun     std::error_code EC;
10772b3d49b6SJonas Devlieghere     auto StatS = std::make_unique<llvm::raw_fd_ostream>(
107882b3e28eSAbhina Sreeskantharajan         StatsFile, EC, llvm::sys::fs::OF_TextWithCRLF);
1079abb6eea1SMatthias Braun     if (EC) {
1080abb6eea1SMatthias Braun       getDiagnostics().Report(diag::warn_fe_unable_to_open_stats_file)
1081abb6eea1SMatthias Braun           << StatsFile << EC.message();
1082abb6eea1SMatthias Braun     } else {
1083abb6eea1SMatthias Braun       llvm::PrintStatisticsJSON(*StatS);
1084abb6eea1SMatthias Braun     }
10854f2bc55dSDaniel Dunbar   }
10864f2bc55dSDaniel Dunbar 
1087bc467933SArgyrios Kyrtzidis   return !getDiagnostics().getClient()->getNumErrors();
10884f2bc55dSDaniel Dunbar }
10894f2bc55dSDaniel Dunbar 
LoadRequestedPlugins()1090f4f9ad0fSVassil Vassilev void CompilerInstance::LoadRequestedPlugins() {
1091f4f9ad0fSVassil Vassilev   // Load any requested plugins.
1092f4f9ad0fSVassil Vassilev   for (const std::string &Path : getFrontendOpts().Plugins) {
1093f4f9ad0fSVassil Vassilev     std::string Error;
1094f4f9ad0fSVassil Vassilev     if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
1095f4f9ad0fSVassil Vassilev       getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)
1096f4f9ad0fSVassil Vassilev           << Path << Error;
1097f4f9ad0fSVassil Vassilev   }
1098f4f9ad0fSVassil Vassilev 
1099f4f9ad0fSVassil Vassilev   // Check if any of the loaded plugins replaces the main AST action
1100f4f9ad0fSVassil Vassilev   for (const FrontendPluginRegistry::entry &Plugin :
1101f4f9ad0fSVassil Vassilev        FrontendPluginRegistry::entries()) {
1102f4f9ad0fSVassil Vassilev     std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
1103f4f9ad0fSVassil Vassilev     if (P->getActionType() == PluginASTAction::ReplaceAction) {
1104f4f9ad0fSVassil Vassilev       getFrontendOpts().ProgramAction = clang::frontend::PluginAction;
1105f4f9ad0fSVassil Vassilev       getFrontendOpts().ActionName = Plugin.getName().str();
1106f4f9ad0fSVassil Vassilev       break;
1107f4f9ad0fSVassil Vassilev     }
1108f4f9ad0fSVassil Vassilev   }
1109f4f9ad0fSVassil Vassilev }
1110f4f9ad0fSVassil Vassilev 
11119fc8faf9SAdrian Prantl /// Determine the appropriate source input kind based on language
1112faeb1d46SDouglas Gregor /// options.
getLanguageFromOptions(const LangOptions & LangOpts)111309d890d7SRainer Orth static Language getLanguageFromOptions(const LangOptions &LangOpts) {
1114faeb1d46SDouglas Gregor   if (LangOpts.OpenCL)
111509d890d7SRainer Orth     return Language::OpenCL;
1116faeb1d46SDouglas Gregor   if (LangOpts.CUDA)
111709d890d7SRainer Orth     return Language::CUDA;
1118fa98390bSErik Pilkington   if (LangOpts.ObjC)
111909d890d7SRainer Orth     return LangOpts.CPlusPlus ? Language::ObjCXX : Language::ObjC;
112009d890d7SRainer Orth   return LangOpts.CPlusPlus ? Language::CXX : Language::C;
1121faeb1d46SDouglas Gregor }
1122faeb1d46SDouglas Gregor 
11239fc8faf9SAdrian Prantl /// Compile a module file for the given module, using the options
1124b797d59fSBen Langmuir /// provided by the importing compiler instance. Returns true if the module
1125b797d59fSBen Langmuir /// was built without errors.
11265d2ed489SRichard Smith static bool
compileModuleImpl(CompilerInstance & ImportingInstance,SourceLocation ImportLoc,StringRef ModuleName,FrontendInputFile Input,StringRef OriginalModuleMapFile,StringRef ModuleFileName,llvm::function_ref<void (CompilerInstance &)> PreBuildStep=[](CompilerInstance &){},llvm::function_ref<void (CompilerInstance &)> PostBuildStep=[](CompilerInstance &){})11275d2ed489SRichard Smith compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
11285d2ed489SRichard Smith                   StringRef ModuleName, FrontendInputFile Input,
11295d2ed489SRichard Smith                   StringRef OriginalModuleMapFile, StringRef ModuleFileName,
11305d2ed489SRichard Smith                   llvm::function_ref<void(CompilerInstance &)> PreBuildStep =
11315d2ed489SRichard Smith                       [](CompilerInstance &) {},
11325d2ed489SRichard Smith                   llvm::function_ref<void(CompilerInstance &)> PostBuildStep =
__anon95e63fe90502(CompilerInstance &) 11335d2ed489SRichard Smith                       [](CompilerInstance &) {}) {
1134d880de2dSAnton Afanasyev   llvm::TimeTraceScope TimeScope("Module Compile", ModuleName);
1135d880de2dSAnton Afanasyev 
1136766a08dfSBen Barham   // Never compile a module that's already finalized - this would cause the
1137766a08dfSBen Barham   // existing module to be freed, causing crashes if it is later referenced
1138766a08dfSBen Barham   if (ImportingInstance.getModuleCache().isPCMFinal(ModuleFileName)) {
1139766a08dfSBen Barham     ImportingInstance.getDiagnostics().Report(
1140766a08dfSBen Barham         ImportLoc, diag::err_module_rebuild_finalized)
1141766a08dfSBen Barham         << ModuleName;
1142766a08dfSBen Barham     return false;
1143766a08dfSBen Barham   }
1144766a08dfSBen Barham 
1145faeb1d46SDouglas Gregor   // Construct a compiler invocation for creating this module.
1146ea4395ebSDavid Blaikie   auto Invocation =
1147ea4395ebSDavid Blaikie       std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation());
114844bf68d8SDouglas Gregor 
1149f545f67dSDouglas Gregor   PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
1150f545f67dSDouglas Gregor 
115144bf68d8SDouglas Gregor   // For any options that aren't intended to affect how a module is built,
115244bf68d8SDouglas Gregor   // reset them to their default values.
11538cf47df7STed Kremenek   Invocation->getLangOpts()->resetNonModularOptions();
1154f545f67dSDouglas Gregor   PPOpts.resetNonModularOptions();
115544bf68d8SDouglas Gregor 
11565dc3899cSDouglas Gregor   // Remove any macro definitions that are explicitly ignored by the module.
11575dc3899cSDouglas Gregor   // They aren't supposed to affect how the module is built anyway.
115860fa2888SDuncan P. N. Exon Smith   HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
115976f0f1ccSKazu Hirata   llvm::erase_if(PPOpts.Macros,
__anon95e63fe90602(const std::pair<std::string, bool> &def) 116076f0f1ccSKazu Hirata                  [&HSOpts](const std::pair<std::string, bool> &def) {
1161bbdd7640SBenjamin Kramer                    StringRef MacroDef = def.first;
116276f0f1ccSKazu Hirata                    return HSOpts.ModulesIgnoreMacros.contains(
116376f0f1ccSKazu Hirata                        llvm::CachedHashString(MacroDef.split('=').first));
1164d245f2e8SKazu Hirata                  });
11655dc3899cSDouglas Gregor 
1166970b2819SBruno Cardoso Lopes   // If the original compiler invocation had -fmodule-name, pass it through.
1167970b2819SBruno Cardoso Lopes   Invocation->getLangOpts()->ModuleName =
1168970b2819SBruno Cardoso Lopes       ImportingInstance.getInvocation().getLangOpts()->ModuleName;
1169970b2819SBruno Cardoso Lopes 
11707d106e42SDouglas Gregor   // Note the name of the module we're building.
1171adcd0268SBenjamin Kramer   Invocation->getLangOpts()->CurrentModule = std::string(ModuleName);
11727d106e42SDouglas Gregor 
11737a626570SDouglas Gregor   // Make sure that the failed-module structure has been allocated in
11747a626570SDouglas Gregor   // the importing instance, and propagate the pointer to the newly-created
11757a626570SDouglas Gregor   // instance.
11767a626570SDouglas Gregor   PreprocessorOptions &ImportingPPOpts
11777a626570SDouglas Gregor     = ImportingInstance.getInvocation().getPreprocessorOpts();
11787a626570SDouglas Gregor   if (!ImportingPPOpts.FailedModules)
1179f95113daSDavid Blaikie     ImportingPPOpts.FailedModules =
1180f95113daSDavid Blaikie         std::make_shared<PreprocessorOptions::FailedModulesSet>();
11817a626570SDouglas Gregor   PPOpts.FailedModules = ImportingPPOpts.FailedModules;
11827a626570SDouglas Gregor 
1183514b636aSDouglas Gregor   // If there is a module map file, build the module using the module map.
1184514b636aSDouglas Gregor   // Set up the inputs/outputs so that we build the module from its umbrella
1185514b636aSDouglas Gregor   // header.
1186514b636aSDouglas Gregor   FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
1187514b636aSDouglas Gregor   FrontendOpts.OutputFile = ModuleFileName.str();
1188514b636aSDouglas Gregor   FrontendOpts.DisableFree = false;
1189c1bbec85SDouglas Gregor   FrontendOpts.GenerateGlobalModuleIndex = false;
1190e75ee0f0SRichard Smith   FrontendOpts.BuildingImplicitModule = true;
1191adcd0268SBenjamin Kramer   FrontendOpts.OriginalModuleMap = std::string(OriginalModuleMapFile);
119260fa2888SDuncan P. N. Exon Smith   // Force implicitly-built modules to hash the content of the module file.
119360fa2888SDuncan P. N. Exon Smith   HSOpts.ModulesHashContent = true;
11945d2ed489SRichard Smith   FrontendOpts.Inputs = {Input};
1195f545f67dSDouglas Gregor 
1196f545f67dSDouglas Gregor   // Don't free the remapped file buffers; they are owned by our caller.
1197f545f67dSDouglas Gregor   PPOpts.RetainRemappedFileBuffers = true;
1198514b636aSDouglas Gregor 
1199514b636aSDouglas Gregor   Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
1200514b636aSDouglas Gregor   assert(ImportingInstance.getInvocation().getModuleHash() ==
1201514b636aSDouglas Gregor          Invocation->getModuleHash() && "Module hash mismatch!");
1202514b636aSDouglas Gregor 
1203514b636aSDouglas Gregor   // Construct a compiler instance that will be used to actually create the
12048bef5cd4SDuncan P. N. Exon Smith   // module.  Since we're sharing an in-memory module cache,
1205030d7d6dSDuncan P. N. Exon Smith   // CompilerInstance::CompilerInstance is responsible for finalizing the
1206030d7d6dSDuncan P. N. Exon Smith   // buffers to prevent use-after-frees.
1207bb165fb0SAdrian Prantl   CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(),
12088bef5cd4SDuncan P. N. Exon Smith                             &ImportingInstance.getModuleCache());
1209ea4395ebSDavid Blaikie   auto &Inv = *Invocation;
1210ea4395ebSDavid Blaikie   Instance.setInvocation(std::move(Invocation));
12116b930967SDouglas Gregor 
12126b930967SDouglas Gregor   Instance.createDiagnostics(new ForwardingDiagnosticConsumer(
12136b930967SDouglas Gregor                                    ImportingInstance.getDiagnosticClient()),
121430071ceaSDouglas Gregor                              /*ShouldOwnClient=*/true);
1215514b636aSDouglas Gregor 
121663365431SDouglas Gregor   // Note that this module is part of the module build stack, so that we
1217af8f0263SDouglas Gregor   // can detect cycles in the module graph.
1218d066d4c8SBen Langmuir   Instance.setFileManager(&ImportingInstance.getFileManager());
1219af8f0263SDouglas Gregor   Instance.createSourceManager(Instance.getFileManager());
1220af8f0263SDouglas Gregor   SourceManager &SourceMgr = Instance.getSourceManager();
122163365431SDouglas Gregor   SourceMgr.setModuleBuildStack(
122263365431SDouglas Gregor     ImportingInstance.getSourceManager().getModuleBuildStack());
12235d2ed489SRichard Smith   SourceMgr.pushModuleBuildStack(ModuleName,
1224af8f0263SDouglas Gregor     FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));
1225af8f0263SDouglas Gregor 
122686d1259cSJustin Bogner   // If we're collecting module dependencies, we need to share a collector
122738c1e6d3SRichard Smith   // between all of the module CompilerInstances. Other than that, we don't
122838c1e6d3SRichard Smith   // want to produce any dependency output from the module build.
122986d1259cSJustin Bogner   Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector());
1230ea4395ebSDavid Blaikie   Inv.getDependencyOutputOpts() = DependencyOutputOptions();
123186d1259cSJustin Bogner 
123299891da7SRichard Smith   ImportingInstance.getDiagnostics().Report(ImportLoc,
123399891da7SRichard Smith                                             diag::remark_module_build)
12345d2ed489SRichard Smith     << ModuleName << ModuleFileName;
12355d2ed489SRichard Smith 
12365d2ed489SRichard Smith   PreBuildStep(Instance);
123799891da7SRichard Smith 
1238514b636aSDouglas Gregor   // Execute the action to actually build the module in-place. Use a separate
1239514b636aSDouglas Gregor   // thread so that we get a stack large enough.
124067a84ec8SBen Langmuir   bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnThread(
__anon95e63fe90702() 1241f74d9466SRichard Smith       [&]() {
1242f74d9466SRichard Smith         GenerateModuleFromModuleMapAction Action;
1243f74d9466SRichard Smith         Instance.ExecuteAction(Action);
1244f74d9466SRichard Smith       },
12450a7b297dSRichard Smith       DesiredStackSize);
12466b930967SDouglas Gregor 
12475d2ed489SRichard Smith   PostBuildStep(Instance);
12485d2ed489SRichard Smith 
124999891da7SRichard Smith   ImportingInstance.getDiagnostics().Report(ImportLoc,
125099891da7SRichard Smith                                             diag::remark_module_build_done)
12515d2ed489SRichard Smith     << ModuleName;
125299891da7SRichard Smith 
125367a84ec8SBen Langmuir   if (Crashed) {
125467a84ec8SBen Langmuir     // Clear the ASTConsumer if it hasn't been already, in case it owns streams
125567a84ec8SBen Langmuir     // that must be closed before clearing output files.
125667a84ec8SBen Langmuir     Instance.setSema(nullptr);
125767a84ec8SBen Langmuir     Instance.setASTConsumer(nullptr);
125867a84ec8SBen Langmuir 
125967a84ec8SBen Langmuir     // Delete any remaining temporary files related to Instance.
126013afbf42SBenjamin Kramer     Instance.clearOutputFiles(/*EraseFiles=*/true);
126167a84ec8SBen Langmuir   }
12625e306b12SDouglas Gregor 
1263a8cb39baSArgyrios Kyrtzidis   // If \p AllowPCMWithCompilerErrors is set return 'success' even if errors
1264a8cb39baSArgyrios Kyrtzidis   // occurred.
1265a8cb39baSArgyrios Kyrtzidis   return !Instance.getDiagnostics().hasErrorOccurred() ||
1266a8cb39baSArgyrios Kyrtzidis          Instance.getFrontendOpts().AllowPCMWithCompilerErrors;
12675d2ed489SRichard Smith }
12685d2ed489SRichard Smith 
getPublicModuleMap(const FileEntry * File,FileManager & FileMgr)126922d97065SBruno Cardoso Lopes static const FileEntry *getPublicModuleMap(const FileEntry *File,
127022d97065SBruno Cardoso Lopes                                            FileManager &FileMgr) {
127122d97065SBruno Cardoso Lopes   StringRef Filename = llvm::sys::path::filename(File->getName());
127222d97065SBruno Cardoso Lopes   SmallString<128> PublicFilename(File->getDir()->getName());
127322d97065SBruno Cardoso Lopes   if (Filename == "module_private.map")
127422d97065SBruno Cardoso Lopes     llvm::sys::path::append(PublicFilename, "module.map");
127522d97065SBruno Cardoso Lopes   else if (Filename == "module.private.modulemap")
127622d97065SBruno Cardoso Lopes     llvm::sys::path::append(PublicFilename, "module.modulemap");
127722d97065SBruno Cardoso Lopes   else
127822d97065SBruno Cardoso Lopes     return nullptr;
12798d323d15SHarlan Haskins   if (auto FE = FileMgr.getFile(PublicFilename))
12808d323d15SHarlan Haskins     return *FE;
12818d323d15SHarlan Haskins   return nullptr;
128222d97065SBruno Cardoso Lopes }
128322d97065SBruno Cardoso Lopes 
12845cca6223SDuncan P. N. Exon Smith /// Compile a module file for the given module in a separate compiler instance,
12855cca6223SDuncan P. N. Exon Smith /// using the options provided by the importing compiler instance. Returns true
12865cca6223SDuncan P. N. Exon Smith /// if the module was built without errors.
compileModule(CompilerInstance & ImportingInstance,SourceLocation ImportLoc,Module * Module,StringRef ModuleFileName)12875cca6223SDuncan P. N. Exon Smith static bool compileModule(CompilerInstance &ImportingInstance,
12885cca6223SDuncan P. N. Exon Smith                           SourceLocation ImportLoc, Module *Module,
12895d2ed489SRichard Smith                           StringRef ModuleFileName) {
12905d2ed489SRichard Smith   InputKind IK(getLanguageFromOptions(ImportingInstance.getLangOpts()),
12915d2ed489SRichard Smith                InputKind::ModuleMap);
12925d2ed489SRichard Smith 
12935d2ed489SRichard Smith   // Get or create the module map that we'll use to build this module.
12945d2ed489SRichard Smith   ModuleMap &ModMap
12955d2ed489SRichard Smith     = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
12965d2ed489SRichard Smith   bool Result;
12975d2ed489SRichard Smith   if (const FileEntry *ModuleMapFile =
12985d2ed489SRichard Smith           ModMap.getContainingModuleMapFile(Module)) {
129922d97065SBruno Cardoso Lopes     // Canonicalize compilation to start with the public module map. This is
130022d97065SBruno Cardoso Lopes     // vital for submodules declarations in the private module maps to be
130122d97065SBruno Cardoso Lopes     // correctly parsed when depending on a top level module in the public one.
130222d97065SBruno Cardoso Lopes     if (const FileEntry *PublicMMFile = getPublicModuleMap(
130322d97065SBruno Cardoso Lopes             ModuleMapFile, ImportingInstance.getFileManager()))
130422d97065SBruno Cardoso Lopes       ModuleMapFile = PublicMMFile;
130522d97065SBruno Cardoso Lopes 
13065d2ed489SRichard Smith     // Use the module map where this module resides.
13075d2ed489SRichard Smith     Result = compileModuleImpl(
13085d2ed489SRichard Smith         ImportingInstance, ImportLoc, Module->getTopLevelModuleName(),
13095d2ed489SRichard Smith         FrontendInputFile(ModuleMapFile->getName(), IK, +Module->IsSystem),
13105d2ed489SRichard Smith         ModMap.getModuleMapFileForUniquing(Module)->getName(),
13115d2ed489SRichard Smith         ModuleFileName);
13125d2ed489SRichard Smith   } else {
13135d2ed489SRichard Smith     // FIXME: We only need to fake up an input file here as a way of
13145d2ed489SRichard Smith     // transporting the module's directory to the module map parser. We should
13155d2ed489SRichard Smith     // be able to do that more directly, and parse from a memory buffer without
13165d2ed489SRichard Smith     // inventing this file.
13175d2ed489SRichard Smith     SmallString<128> FakeModuleMapFile(Module->Directory->getName());
13185d2ed489SRichard Smith     llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map");
13195d2ed489SRichard Smith 
13205d2ed489SRichard Smith     std::string InferredModuleMapContent;
13215d2ed489SRichard Smith     llvm::raw_string_ostream OS(InferredModuleMapContent);
13225d2ed489SRichard Smith     Module->print(OS);
13235d2ed489SRichard Smith     OS.flush();
13245d2ed489SRichard Smith 
13255d2ed489SRichard Smith     Result = compileModuleImpl(
13265d2ed489SRichard Smith         ImportingInstance, ImportLoc, Module->getTopLevelModuleName(),
13275d2ed489SRichard Smith         FrontendInputFile(FakeModuleMapFile, IK, +Module->IsSystem),
13285d2ed489SRichard Smith         ModMap.getModuleMapFileForUniquing(Module)->getName(),
13295d2ed489SRichard Smith         ModuleFileName,
13305d2ed489SRichard Smith         [&](CompilerInstance &Instance) {
13315d2ed489SRichard Smith       std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
13325d2ed489SRichard Smith           llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
13335d2ed489SRichard Smith       ModuleMapFile = Instance.getFileManager().getVirtualFile(
13345d2ed489SRichard Smith           FakeModuleMapFile, InferredModuleMapContent.size(), 0);
13355d2ed489SRichard Smith       Instance.getSourceManager().overrideFileContents(
13365d2ed489SRichard Smith           ModuleMapFile, std::move(ModuleMapBuffer));
13375d2ed489SRichard Smith     });
13385d2ed489SRichard Smith   }
13395d2ed489SRichard Smith 
13405e306b12SDouglas Gregor   // We've rebuilt a module. If we're allowed to generate or update the global
13415e306b12SDouglas Gregor   // module index, record that fact in the importing compiler instance.
1342c1bbec85SDouglas Gregor   if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) {
13435e306b12SDouglas Gregor     ImportingInstance.setBuildGlobalModuleIndex(true);
13445e306b12SDouglas Gregor   }
1345b797d59fSBen Langmuir 
13465d2ed489SRichard Smith   return Result;
1347faeb1d46SDouglas Gregor }
1348faeb1d46SDouglas Gregor 
1349c130300fSDuncan P. N. Exon Smith /// Read the AST right after compiling the module.
readASTAfterCompileModule(CompilerInstance & ImportingInstance,SourceLocation ImportLoc,SourceLocation ModuleNameLoc,Module * Module,StringRef ModuleFileName,bool * OutOfDate)1350c130300fSDuncan P. N. Exon Smith static bool readASTAfterCompileModule(CompilerInstance &ImportingInstance,
1351c130300fSDuncan P. N. Exon Smith                                       SourceLocation ImportLoc,
1352c130300fSDuncan P. N. Exon Smith                                       SourceLocation ModuleNameLoc,
1353c130300fSDuncan P. N. Exon Smith                                       Module *Module, StringRef ModuleFileName,
1354c130300fSDuncan P. N. Exon Smith                                       bool *OutOfDate) {
1355c130300fSDuncan P. N. Exon Smith   DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics();
1356c130300fSDuncan P. N. Exon Smith 
1357c130300fSDuncan P. N. Exon Smith   unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing;
1358c130300fSDuncan P. N. Exon Smith   if (OutOfDate)
1359c130300fSDuncan P. N. Exon Smith     ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate;
1360c130300fSDuncan P. N. Exon Smith 
1361c130300fSDuncan P. N. Exon Smith   // Try to read the module file, now that we've compiled it.
1362c130300fSDuncan P. N. Exon Smith   ASTReader::ASTReadResult ReadResult =
1363c130300fSDuncan P. N. Exon Smith       ImportingInstance.getASTReader()->ReadAST(
1364c130300fSDuncan P. N. Exon Smith           ModuleFileName, serialization::MK_ImplicitModule, ImportLoc,
1365c130300fSDuncan P. N. Exon Smith           ModuleLoadCapabilities);
1366c130300fSDuncan P. N. Exon Smith   if (ReadResult == ASTReader::Success)
1367c130300fSDuncan P. N. Exon Smith     return true;
1368c130300fSDuncan P. N. Exon Smith 
1369c130300fSDuncan P. N. Exon Smith   // The caller wants to handle out-of-date failures.
1370c130300fSDuncan P. N. Exon Smith   if (OutOfDate && ReadResult == ASTReader::OutOfDate) {
1371c130300fSDuncan P. N. Exon Smith     *OutOfDate = true;
1372c130300fSDuncan P. N. Exon Smith     return false;
1373c130300fSDuncan P. N. Exon Smith   }
1374c130300fSDuncan P. N. Exon Smith 
1375c130300fSDuncan P. N. Exon Smith   // The ASTReader didn't diagnose the error, so conservatively report it.
1376c130300fSDuncan P. N. Exon Smith   if (ReadResult == ASTReader::Missing || !Diags.hasErrorOccurred())
1377c130300fSDuncan P. N. Exon Smith     Diags.Report(ModuleNameLoc, diag::err_module_not_built)
1378c130300fSDuncan P. N. Exon Smith       << Module->Name << SourceRange(ImportLoc, ModuleNameLoc);
1379c130300fSDuncan P. N. Exon Smith 
1380c130300fSDuncan P. N. Exon Smith   return false;
1381c130300fSDuncan P. N. Exon Smith }
1382c130300fSDuncan P. N. Exon Smith 
13835cca6223SDuncan P. N. Exon Smith /// Compile a module in a separate compiler instance and read the AST,
13845cca6223SDuncan P. N. Exon Smith /// returning true if the module compiles without errors.
compileModuleAndReadASTImpl(CompilerInstance & ImportingInstance,SourceLocation ImportLoc,SourceLocation ModuleNameLoc,Module * Module,StringRef ModuleFileName)1385c130300fSDuncan P. N. Exon Smith static bool compileModuleAndReadASTImpl(CompilerInstance &ImportingInstance,
1386c130300fSDuncan P. N. Exon Smith                                         SourceLocation ImportLoc,
1387c130300fSDuncan P. N. Exon Smith                                         SourceLocation ModuleNameLoc,
1388c130300fSDuncan P. N. Exon Smith                                         Module *Module,
1389c130300fSDuncan P. N. Exon Smith                                         StringRef ModuleFileName) {
1390c130300fSDuncan P. N. Exon Smith   if (!compileModule(ImportingInstance, ModuleNameLoc, Module,
1391c130300fSDuncan P. N. Exon Smith                      ModuleFileName)) {
1392c130300fSDuncan P. N. Exon Smith     ImportingInstance.getDiagnostics().Report(ModuleNameLoc,
1393c130300fSDuncan P. N. Exon Smith                                               diag::err_module_not_built)
1394c130300fSDuncan P. N. Exon Smith         << Module->Name << SourceRange(ImportLoc, ModuleNameLoc);
1395c130300fSDuncan P. N. Exon Smith     return false;
1396c130300fSDuncan P. N. Exon Smith   }
1397c130300fSDuncan P. N. Exon Smith 
1398c130300fSDuncan P. N. Exon Smith   return readASTAfterCompileModule(ImportingInstance, ImportLoc, ModuleNameLoc,
1399c130300fSDuncan P. N. Exon Smith                                    Module, ModuleFileName,
1400c130300fSDuncan P. N. Exon Smith                                    /*OutOfDate=*/nullptr);
1401c130300fSDuncan P. N. Exon Smith }
1402c130300fSDuncan P. N. Exon Smith 
1403c130300fSDuncan P. N. Exon Smith /// Compile a module in a separate compiler instance and read the AST,
1404c130300fSDuncan P. N. Exon Smith /// returning true if the module compiles without errors, using a lock manager
1405c130300fSDuncan P. N. Exon Smith /// to avoid building the same module in multiple compiler instances.
14065cca6223SDuncan P. N. Exon Smith ///
14075cca6223SDuncan P. N. Exon Smith /// Uses a lock file manager and exponential backoff to reduce the chances that
14085cca6223SDuncan P. N. Exon Smith /// multiple instances will compete to create the same module.  On timeout,
14095cca6223SDuncan P. N. Exon Smith /// deletes the lock file in order to avoid deadlock from crashing processes or
14105cca6223SDuncan P. N. Exon Smith /// bugs in the lock file manager.
compileModuleAndReadASTBehindLock(CompilerInstance & ImportingInstance,SourceLocation ImportLoc,SourceLocation ModuleNameLoc,Module * Module,StringRef ModuleFileName)1411c130300fSDuncan P. N. Exon Smith static bool compileModuleAndReadASTBehindLock(
1412c130300fSDuncan P. N. Exon Smith     CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
1413c130300fSDuncan P. N. Exon Smith     SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName) {
1414d213aab7SBen Langmuir   DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics();
1415d213aab7SBen Langmuir 
1416b714f73dSDuncan P. N. Exon Smith   Diags.Report(ModuleNameLoc, diag::remark_module_lock)
1417b714f73dSDuncan P. N. Exon Smith       << ModuleFileName << Module->Name;
1418b714f73dSDuncan P. N. Exon Smith 
14194382fe74SArgyrios Kyrtzidis   // FIXME: have LockFileManager return an error_code so that we can
14204382fe74SArgyrios Kyrtzidis   // avoid the mkdir when the directory already exists.
14214382fe74SArgyrios Kyrtzidis   StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
14224382fe74SArgyrios Kyrtzidis   llvm::sys::fs::create_directories(Dir);
14234382fe74SArgyrios Kyrtzidis 
142440446663SKazu Hirata   while (true) {
14254382fe74SArgyrios Kyrtzidis     llvm::LockFileManager Locked(ModuleFileName);
14264382fe74SArgyrios Kyrtzidis     switch (Locked) {
14274382fe74SArgyrios Kyrtzidis     case llvm::LockFileManager::LFS_Error:
14288bef5cd4SDuncan P. N. Exon Smith       // ModuleCache takes care of correctness and locks are only necessary for
14295a0af1fcSBruno Cardoso Lopes       // performance. Fallback to building the module in case of any lock
14305a0af1fcSBruno Cardoso Lopes       // related errors.
14315a0af1fcSBruno Cardoso Lopes       Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure)
14324a52222cSBruno Cardoso Lopes           << Module->Name << Locked.getErrorMessage();
14335a0af1fcSBruno Cardoso Lopes       // Clear out any potential leftover.
14345a0af1fcSBruno Cardoso Lopes       Locked.unsafeRemoveLockFile();
14354dc0b1acSReid Kleckner       LLVM_FALLTHROUGH;
14364382fe74SArgyrios Kyrtzidis     case llvm::LockFileManager::LFS_Owned:
1437dbdc0368SBen Langmuir       // We're responsible for building the module ourselves.
1438c130300fSDuncan P. N. Exon Smith       return compileModuleAndReadASTImpl(ImportingInstance, ImportLoc,
1439c130300fSDuncan P. N. Exon Smith                                          ModuleNameLoc, Module, ModuleFileName);
14404382fe74SArgyrios Kyrtzidis 
14414382fe74SArgyrios Kyrtzidis     case llvm::LockFileManager::LFS_Shared:
1442c130300fSDuncan P. N. Exon Smith       break; // The interesting case.
1443c130300fSDuncan P. N. Exon Smith     }
1444c130300fSDuncan P. N. Exon Smith 
14454382fe74SArgyrios Kyrtzidis     // Someone else is responsible for building the module. Wait for them to
14464382fe74SArgyrios Kyrtzidis     // finish.
14471daf4801SBen Langmuir     switch (Locked.waitForUnlock()) {
14481daf4801SBen Langmuir     case llvm::LockFileManager::Res_Success:
1449c130300fSDuncan P. N. Exon Smith       break; // The interesting case.
14501daf4801SBen Langmuir     case llvm::LockFileManager::Res_OwnerDied:
14511daf4801SBen Langmuir       continue; // try again to get the lock.
14521daf4801SBen Langmuir     case llvm::LockFileManager::Res_Timeout:
14538bef5cd4SDuncan P. N. Exon Smith       // Since ModuleCache takes care of correctness, we try waiting for
14548bef5cd4SDuncan P. N. Exon Smith       // another process to complete the build so clang does not do it done
14558bef5cd4SDuncan P. N. Exon Smith       // twice. If case of timeout, build it ourselves.
14565a0af1fcSBruno Cardoso Lopes       Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout)
14571daf4801SBen Langmuir           << Module->Name;
14582a8c18d9SAlexander Kornienko       // Clear the lock file so that future invocations can make progress.
14591daf4801SBen Langmuir       Locked.unsafeRemoveLockFile();
14605a0af1fcSBruno Cardoso Lopes       continue;
14611daf4801SBen Langmuir     }
14624382fe74SArgyrios Kyrtzidis 
1463c130300fSDuncan P. N. Exon Smith     // Read the module that was just written by someone else.
1464c130300fSDuncan P. N. Exon Smith     bool OutOfDate = false;
1465c130300fSDuncan P. N. Exon Smith     if (readASTAfterCompileModule(ImportingInstance, ImportLoc, ModuleNameLoc,
1466c130300fSDuncan P. N. Exon Smith                                   Module, ModuleFileName, &OutOfDate))
1467c130300fSDuncan P. N. Exon Smith       return true;
1468c130300fSDuncan P. N. Exon Smith     if (!OutOfDate)
1469c130300fSDuncan P. N. Exon Smith       return false;
1470dbdc0368SBen Langmuir 
1471dbdc0368SBen Langmuir     // The module may be out of date in the presence of file system races,
1472dbdc0368SBen Langmuir     // or if one of its imports depends on header search paths that are not
1473dbdc0368SBen Langmuir     // consistent with this ImportingInstance.  Try again...
14744382fe74SArgyrios Kyrtzidis   }
14754382fe74SArgyrios Kyrtzidis }
14764382fe74SArgyrios Kyrtzidis 
1477b714f73dSDuncan P. N. Exon Smith /// Compile a module in a separate compiler instance and read the AST,
1478b714f73dSDuncan P. N. Exon Smith /// returning true if the module compiles without errors, potentially using a
1479b714f73dSDuncan P. N. Exon Smith /// lock manager to avoid building the same module in multiple compiler
1480b714f73dSDuncan P. N. Exon Smith /// instances.
compileModuleAndReadAST(CompilerInstance & ImportingInstance,SourceLocation ImportLoc,SourceLocation ModuleNameLoc,Module * Module,StringRef ModuleFileName)1481b714f73dSDuncan P. N. Exon Smith static bool compileModuleAndReadAST(CompilerInstance &ImportingInstance,
1482b714f73dSDuncan P. N. Exon Smith                                     SourceLocation ImportLoc,
1483b714f73dSDuncan P. N. Exon Smith                                     SourceLocation ModuleNameLoc,
1484b714f73dSDuncan P. N. Exon Smith                                     Module *Module, StringRef ModuleFileName) {
1485b714f73dSDuncan P. N. Exon Smith   return ImportingInstance.getInvocation()
1486b714f73dSDuncan P. N. Exon Smith                  .getFrontendOpts()
1487b714f73dSDuncan P. N. Exon Smith                  .BuildingImplicitModuleUsesLock
1488b714f73dSDuncan P. N. Exon Smith              ? compileModuleAndReadASTBehindLock(ImportingInstance, ImportLoc,
1489b714f73dSDuncan P. N. Exon Smith                                                  ModuleNameLoc, Module,
1490b714f73dSDuncan P. N. Exon Smith                                                  ModuleFileName)
1491b714f73dSDuncan P. N. Exon Smith              : compileModuleAndReadASTImpl(ImportingInstance, ImportLoc,
1492b714f73dSDuncan P. N. Exon Smith                                            ModuleNameLoc, Module,
1493b714f73dSDuncan P. N. Exon Smith                                            ModuleFileName);
1494b714f73dSDuncan P. N. Exon Smith }
1495b714f73dSDuncan P. N. Exon Smith 
14969fc8faf9SAdrian Prantl /// Diagnose differences between the current definition of the given
149735b13eceSDouglas Gregor /// configuration macro and the definition provided on the command line.
checkConfigMacro(Preprocessor & PP,StringRef ConfigMacro,Module * Mod,SourceLocation ImportLoc)149835b13eceSDouglas Gregor static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,
149935b13eceSDouglas Gregor                              Module *Mod, SourceLocation ImportLoc) {
150035b13eceSDouglas Gregor   IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro);
150135b13eceSDouglas Gregor   SourceManager &SourceMgr = PP.getSourceManager();
150235b13eceSDouglas Gregor 
150335b13eceSDouglas Gregor   // If this identifier has never had a macro definition, then it could
150435b13eceSDouglas Gregor   // not have changed.
150535b13eceSDouglas Gregor   if (!Id->hadMacroDefinition())
150635b13eceSDouglas Gregor     return;
150720e883e5SRichard Smith   auto *LatestLocalMD = PP.getLocalMacroDirectiveHistory(Id);
150835b13eceSDouglas Gregor 
150920e883e5SRichard Smith   // Find the macro definition from the command line.
151020e883e5SRichard Smith   MacroInfo *CmdLineDefinition = nullptr;
151120e883e5SRichard Smith   for (auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) {
151235b13eceSDouglas Gregor     // We only care about the predefines buffer.
151320e883e5SRichard Smith     FileID FID = SourceMgr.getFileID(MD->getLocation());
151420e883e5SRichard Smith     if (FID.isInvalid() || FID != PP.getPredefinesFileID())
151535b13eceSDouglas Gregor       continue;
151620e883e5SRichard Smith     if (auto *DMD = dyn_cast<DefMacroDirective>(MD))
151720e883e5SRichard Smith       CmdLineDefinition = DMD->getMacroInfo();
151820e883e5SRichard Smith     break;
151920e883e5SRichard Smith   }
152035b13eceSDouglas Gregor 
152120e883e5SRichard Smith   auto *CurrentDefinition = PP.getMacroInfo(Id);
152220e883e5SRichard Smith   if (CurrentDefinition == CmdLineDefinition) {
152320e883e5SRichard Smith     // Macro matches. Nothing to do.
152420e883e5SRichard Smith   } else if (!CurrentDefinition) {
152535b13eceSDouglas Gregor     // This macro was defined on the command line, then #undef'd later.
152635b13eceSDouglas Gregor     // Complain.
152735b13eceSDouglas Gregor     PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
152835b13eceSDouglas Gregor       << true << ConfigMacro << Mod->getFullModuleName();
152920e883e5SRichard Smith     auto LatestDef = LatestLocalMD->getDefinition();
153020e883e5SRichard Smith     assert(LatestDef.isUndefined() &&
153120e883e5SRichard Smith            "predefined macro went away with no #undef?");
1532b6210dffSArgyrios Kyrtzidis     PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
153335b13eceSDouglas Gregor       << true;
153435b13eceSDouglas Gregor     return;
153520e883e5SRichard Smith   } else if (!CmdLineDefinition) {
153620e883e5SRichard Smith     // There was no definition for this macro in the predefines buffer,
153720e883e5SRichard Smith     // but there was a local definition. Complain.
153835b13eceSDouglas Gregor     PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
153935b13eceSDouglas Gregor       << false << ConfigMacro << Mod->getFullModuleName();
154020e883e5SRichard Smith     PP.Diag(CurrentDefinition->getDefinitionLoc(),
154120e883e5SRichard Smith             diag::note_module_def_undef_here)
154235b13eceSDouglas Gregor       << false;
154320e883e5SRichard Smith   } else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP,
154420e883e5SRichard Smith                                                /*Syntactically=*/true)) {
154535b13eceSDouglas Gregor     // The macro definitions differ.
154635b13eceSDouglas Gregor     PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
154735b13eceSDouglas Gregor       << false << ConfigMacro << Mod->getFullModuleName();
154820e883e5SRichard Smith     PP.Diag(CurrentDefinition->getDefinitionLoc(),
154920e883e5SRichard Smith             diag::note_module_def_undef_here)
155035b13eceSDouglas Gregor       << false;
155135b13eceSDouglas Gregor   }
155220e883e5SRichard Smith }
155335b13eceSDouglas Gregor 
15549fc8faf9SAdrian Prantl /// Write a new timestamp file with the given path.
writeTimestampFile(StringRef TimestampFile)1555527b1c95SDouglas Gregor static void writeTimestampFile(StringRef TimestampFile) {
1556dae941a6SRafael Espindola   std::error_code EC;
1557d9b948b6SFangrui Song   llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::OF_None);
1558527b1c95SDouglas Gregor }
1559527b1c95SDouglas Gregor 
15609fc8faf9SAdrian Prantl /// Prune the module cache of modules that haven't been accessed in
1561527b1c95SDouglas Gregor /// a long time.
pruneModuleCache(const HeaderSearchOptions & HSOpts)1562527b1c95SDouglas Gregor static void pruneModuleCache(const HeaderSearchOptions &HSOpts) {
1563930ada91SVolodymyr Sapsai   llvm::sys::fs::file_status StatBuf;
1564527b1c95SDouglas Gregor   llvm::SmallString<128> TimestampFile;
1565527b1c95SDouglas Gregor   TimestampFile = HSOpts.ModuleCachePath;
15663938f0c7SRichard Smith   assert(!TimestampFile.empty());
1567527b1c95SDouglas Gregor   llvm::sys::path::append(TimestampFile, "modules.timestamp");
1568527b1c95SDouglas Gregor 
1569527b1c95SDouglas Gregor   // Try to stat() the timestamp file.
1570930ada91SVolodymyr Sapsai   if (std::error_code EC = llvm::sys::fs::status(TimestampFile, StatBuf)) {
1571527b1c95SDouglas Gregor     // If the timestamp file wasn't there, create one now.
1572930ada91SVolodymyr Sapsai     if (EC == std::errc::no_such_file_or_directory) {
1573527b1c95SDouglas Gregor       writeTimestampFile(TimestampFile);
1574527b1c95SDouglas Gregor     }
1575527b1c95SDouglas Gregor     return;
1576527b1c95SDouglas Gregor   }
1577527b1c95SDouglas Gregor 
1578527b1c95SDouglas Gregor   // Check whether the time stamp is older than our pruning interval.
1579527b1c95SDouglas Gregor   // If not, do nothing.
1580930ada91SVolodymyr Sapsai   time_t TimeStampModTime =
1581930ada91SVolodymyr Sapsai       llvm::sys::toTimeT(StatBuf.getLastModificationTime());
158249a2790fSCraig Topper   time_t CurrentTime = time(nullptr);
1583dbcf5037SBenjamin Kramer   if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval))
1584527b1c95SDouglas Gregor     return;
1585527b1c95SDouglas Gregor 
1586527b1c95SDouglas Gregor   // Write a new timestamp file so that nobody else attempts to prune.
1587527b1c95SDouglas Gregor   // There is a benign race condition here, if two Clang instances happen to
1588527b1c95SDouglas Gregor   // notice at the same time that the timestamp is out-of-date.
1589527b1c95SDouglas Gregor   writeTimestampFile(TimestampFile);
1590527b1c95SDouglas Gregor 
1591527b1c95SDouglas Gregor   // Walk the entire module cache, looking for unused module files and module
1592527b1c95SDouglas Gregor   // indices.
1593c080917eSRafael Espindola   std::error_code EC;
1594527b1c95SDouglas Gregor   SmallString<128> ModuleCachePathNative;
1595527b1c95SDouglas Gregor   llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative);
159692e1b62dSYaron Keren   for (llvm::sys::fs::directory_iterator Dir(ModuleCachePathNative, EC), DirEnd;
1597527b1c95SDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
1598527b1c95SDouglas Gregor     // If we don't have a directory, there's nothing to look into.
1599a07f720aSRafael Espindola     if (!llvm::sys::fs::is_directory(Dir->path()))
1600527b1c95SDouglas Gregor       continue;
1601527b1c95SDouglas Gregor 
1602527b1c95SDouglas Gregor     // Walk all of the files within this directory.
1603527b1c95SDouglas Gregor     for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd;
1604527b1c95SDouglas Gregor          File != FileEnd && !EC; File.increment(EC)) {
1605527b1c95SDouglas Gregor       // We only care about module and global module index files.
1606f430da4dSDmitri Gribenko       StringRef Extension = llvm::sys::path::extension(File->path());
1607f430da4dSDmitri Gribenko       if (Extension != ".pcm" && Extension != ".timestamp" &&
1608f430da4dSDmitri Gribenko           llvm::sys::path::filename(File->path()) != "modules.idx")
1609527b1c95SDouglas Gregor         continue;
1610527b1c95SDouglas Gregor 
1611527b1c95SDouglas Gregor       // Look at this file. If we can't stat it, there's nothing interesting
1612527b1c95SDouglas Gregor       // there.
1613930ada91SVolodymyr Sapsai       if (llvm::sys::fs::status(File->path(), StatBuf))
1614527b1c95SDouglas Gregor         continue;
1615527b1c95SDouglas Gregor 
1616527b1c95SDouglas Gregor       // If the file has been used recently enough, leave it there.
1617930ada91SVolodymyr Sapsai       time_t FileAccessTime = llvm::sys::toTimeT(StatBuf.getLastAccessedTime());
1618dbcf5037SBenjamin Kramer       if (CurrentTime - FileAccessTime <=
1619dbcf5037SBenjamin Kramer               time_t(HSOpts.ModuleCachePruneAfter)) {
1620527b1c95SDouglas Gregor         continue;
1621527b1c95SDouglas Gregor       }
1622527b1c95SDouglas Gregor 
1623527b1c95SDouglas Gregor       // Remove the file.
1624f430da4dSDmitri Gribenko       llvm::sys::fs::remove(File->path());
1625f430da4dSDmitri Gribenko 
1626f430da4dSDmitri Gribenko       // Remove the timestamp file.
1627f430da4dSDmitri Gribenko       std::string TimpestampFilename = File->path() + ".timestamp";
1628f430da4dSDmitri Gribenko       llvm::sys::fs::remove(TimpestampFilename);
1629527b1c95SDouglas Gregor     }
1630527b1c95SDouglas Gregor 
1631527b1c95SDouglas Gregor     // If we removed all of the files in the directory, remove the directory
1632527b1c95SDouglas Gregor     // itself.
1633f430da4dSDmitri Gribenko     if (llvm::sys::fs::directory_iterator(Dir->path(), EC) ==
1634f430da4dSDmitri Gribenko             llvm::sys::fs::directory_iterator() && !EC)
16352a008784SRafael Espindola       llvm::sys::fs::remove(Dir->path());
1636527b1c95SDouglas Gregor   }
1637527b1c95SDouglas Gregor }
1638527b1c95SDouglas Gregor 
createASTReader()163920d51b2fSDuncan P. N. Exon Smith void CompilerInstance::createASTReader() {
164020d51b2fSDuncan P. N. Exon Smith   if (TheASTReader)
164187008317SDuncan P. N. Exon Smith     return;
164287008317SDuncan P. N. Exon Smith 
16432255f2ceSJohn Thompson   if (!hasASTContext())
16442255f2ceSJohn Thompson     createASTContext();
16452255f2ceSJohn Thompson 
1646580dd296SChandler Carruth   // If we're implicitly building modules but not currently recursively
1647580dd296SChandler Carruth   // building a module, check whether we need to prune the module cache.
16483938f0c7SRichard Smith   if (getSourceManager().getModuleBuildStack().empty() &&
16493938f0c7SRichard Smith       !getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() &&
16502255f2ceSJohn Thompson       getHeaderSearchOpts().ModuleCachePruneInterval > 0 &&
16512255f2ceSJohn Thompson       getHeaderSearchOpts().ModuleCachePruneAfter > 0) {
16522255f2ceSJohn Thompson     pruneModuleCache(getHeaderSearchOpts());
16532255f2ceSJohn Thompson   }
16542255f2ceSJohn Thompson 
16552255f2ceSJohn Thompson   HeaderSearchOptions &HSOpts = getHeaderSearchOpts();
16562255f2ceSJohn Thompson   std::string Sysroot = HSOpts.Sysroot;
16572255f2ceSJohn Thompson   const PreprocessorOptions &PPOpts = getPreprocessorOpts();
16585834996fSBen Barham   const FrontendOptions &FEOpts = getFrontendOpts();
1659ce18a187SRichard Smith   std::unique_ptr<llvm::Timer> ReadTimer;
16605834996fSBen Barham 
1661ce18a187SRichard Smith   if (FrontendTimerGroup)
16622b3d49b6SJonas Devlieghere     ReadTimer = std::make_unique<llvm::Timer>("reading_modules",
1663ae032b6cSMatthias Braun                                                 "Reading modules",
1664ce18a187SRichard Smith                                                 *FrontendTimerGroup);
166520d51b2fSDuncan P. N. Exon Smith   TheASTReader = new ASTReader(
16668bef5cd4SDuncan P. N. Exon Smith       getPreprocessor(), getModuleCache(), &getASTContext(),
16678bef5cd4SDuncan P. N. Exon Smith       getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions,
1668b0e89906SArgyrios Kyrtzidis       Sysroot.empty() ? "" : Sysroot.c_str(),
1669b0e89906SArgyrios Kyrtzidis       PPOpts.DisablePCHOrModuleValidation,
16705834996fSBen Barham       /*AllowASTWithCompilerErrors=*/FEOpts.AllowPCMWithCompilerErrors,
167120d51b2fSDuncan P. N. Exon Smith       /*AllowConfigurationMismatch=*/false, HSOpts.ModulesValidateSystemHeaders,
16721731fc88SBruno Cardoso Lopes       HSOpts.ValidateASTInputFilesContent,
16738bef5cd4SDuncan P. N. Exon Smith       getFrontendOpts().UseGlobalModuleIndex, std::move(ReadTimer));
16742255f2ceSJohn Thompson   if (hasASTConsumer()) {
167520d51b2fSDuncan P. N. Exon Smith     TheASTReader->setDeserializationListener(
16762255f2ceSJohn Thompson         getASTConsumer().GetASTDeserializationListener());
16772255f2ceSJohn Thompson     getASTContext().setASTMutationListener(
16782255f2ceSJohn Thompson       getASTConsumer().GetASTMutationListener());
16792255f2ceSJohn Thompson   }
168020d51b2fSDuncan P. N. Exon Smith   getASTContext().setExternalSource(TheASTReader);
16812255f2ceSJohn Thompson   if (hasSema())
168220d51b2fSDuncan P. N. Exon Smith     TheASTReader->InitializeSema(getSema());
1683293534b1SRichard Smith   if (hasASTConsumer())
168420d51b2fSDuncan P. N. Exon Smith     TheASTReader->StartTranslationUnit(&getASTConsumer());
168503f7e611SRichard Smith 
168603f7e611SRichard Smith   for (auto &Listener : DependencyCollectors)
168720d51b2fSDuncan P. N. Exon Smith     Listener->attachToASTReader(*TheASTReader);
16882255f2ceSJohn Thompson }
16892255f2ceSJohn Thompson 
loadModuleFile(StringRef FileName)1690d4b230b3SRichard Smith bool CompilerInstance::loadModuleFile(StringRef FileName) {
1691ce18a187SRichard Smith   llvm::Timer Timer;
1692ce18a187SRichard Smith   if (FrontendTimerGroup)
1693ae032b6cSMatthias Braun     Timer.init("preloading." + FileName.str(), "Preloading " + FileName.str(),
1694ae032b6cSMatthias Braun                *FrontendTimerGroup);
1695ce18a187SRichard Smith   llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr);
1696ce18a187SRichard Smith 
16977f330cdbSRichard Smith   // If we don't already have an ASTReader, create one now.
169820d51b2fSDuncan P. N. Exon Smith   if (!TheASTReader)
169920d51b2fSDuncan P. N. Exon Smith     createASTReader();
17007f330cdbSRichard Smith 
17017a985e1bSRichard Smith   // If -Wmodule-file-config-mismatch is mapped as an error or worse, allow the
17027a985e1bSRichard Smith   // ASTReader to diagnose it, since it can produce better errors that we can.
17037a985e1bSRichard Smith   bool ConfigMismatchIsRecoverable =
17047a985e1bSRichard Smith       getDiagnostics().getDiagnosticLevel(diag::warn_module_config_mismatch,
17057a985e1bSRichard Smith                                           SourceLocation())
17067a985e1bSRichard Smith         <= DiagnosticsEngine::Warning;
17077a985e1bSRichard Smith 
170808c8016cSJan Svoboda   auto Listener = std::make_unique<ReadModuleNames>(*PP);
17090f99d6a4SRichard Smith   auto &ListenerRef = *Listener;
171020d51b2fSDuncan P. N. Exon Smith   ASTReader::ListenerScope ReadModuleNamesListener(*TheASTReader,
17110f99d6a4SRichard Smith                                                    std::move(Listener));
17127f330cdbSRichard Smith 
17130f99d6a4SRichard Smith   // Try to load the module file.
171420d51b2fSDuncan P. N. Exon Smith   switch (TheASTReader->ReadAST(
17157a985e1bSRichard Smith       FileName, serialization::MK_ExplicitModule, SourceLocation(),
17167a985e1bSRichard Smith       ConfigMismatchIsRecoverable ? ASTReader::ARR_ConfigurationMismatch : 0)) {
171795dc57a6SRichard Smith   case ASTReader::Success:
17180f99d6a4SRichard Smith     // We successfully loaded the module file; remember the set of provided
17190f99d6a4SRichard Smith     // modules so that we don't try to load implicit modules for them.
17200f99d6a4SRichard Smith     ListenerRef.registerAll();
1721d4b230b3SRichard Smith     return true;
172295dc57a6SRichard Smith 
172395dc57a6SRichard Smith   case ASTReader::ConfigurationMismatch:
172495dc57a6SRichard Smith     // Ignore unusable module files.
172595dc57a6SRichard Smith     getDiagnostics().Report(SourceLocation(), diag::warn_module_config_mismatch)
172695dc57a6SRichard Smith         << FileName;
17278a308ec2SRichard Smith     // All modules provided by any files we tried and failed to load are now
17288a308ec2SRichard Smith     // unavailable; includes of those modules should now be handled textually.
17298a308ec2SRichard Smith     ListenerRef.markAllUnavailable();
173095dc57a6SRichard Smith     return true;
173195dc57a6SRichard Smith 
173295dc57a6SRichard Smith   default:
173395dc57a6SRichard Smith     return false;
173495dc57a6SRichard Smith   }
1735e842a474SRichard Smith }
1736e842a474SRichard Smith 
17375cca6223SDuncan P. N. Exon Smith namespace {
17385cca6223SDuncan P. N. Exon Smith enum ModuleSource {
17395cca6223SDuncan P. N. Exon Smith   MS_ModuleNotFound,
17405cca6223SDuncan P. N. Exon Smith   MS_ModuleCache,
17415cca6223SDuncan P. N. Exon Smith   MS_PrebuiltModulePath,
17425cca6223SDuncan P. N. Exon Smith   MS_ModuleBuildPragma
17435cca6223SDuncan P. N. Exon Smith };
17445cca6223SDuncan P. N. Exon Smith } // end namespace
17455cca6223SDuncan P. N. Exon Smith 
17465cca6223SDuncan P. N. Exon Smith /// Select a source for loading the named module and compute the filename to
17475cca6223SDuncan P. N. Exon Smith /// load it from.
selectModuleSource(Module * M,StringRef ModuleName,std::string & ModuleFilename,const std::map<std::string,std::string,std::less<>> & BuiltModules,HeaderSearch & HS)1748ef83d46bSBenjamin Kramer static ModuleSource selectModuleSource(
1749ef83d46bSBenjamin Kramer     Module *M, StringRef ModuleName, std::string &ModuleFilename,
1750ef83d46bSBenjamin Kramer     const std::map<std::string, std::string, std::less<>> &BuiltModules,
17515cca6223SDuncan P. N. Exon Smith     HeaderSearch &HS) {
17525cca6223SDuncan P. N. Exon Smith   assert(ModuleFilename.empty() && "Already has a module source?");
17535cca6223SDuncan P. N. Exon Smith 
17545cca6223SDuncan P. N. Exon Smith   // Check to see if the module has been built as part of this compilation
17555cca6223SDuncan P. N. Exon Smith   // via a module build pragma.
1756ef83d46bSBenjamin Kramer   auto BuiltModuleIt = BuiltModules.find(ModuleName);
17575cca6223SDuncan P. N. Exon Smith   if (BuiltModuleIt != BuiltModules.end()) {
17585cca6223SDuncan P. N. Exon Smith     ModuleFilename = BuiltModuleIt->second;
17595cca6223SDuncan P. N. Exon Smith     return MS_ModuleBuildPragma;
17605cca6223SDuncan P. N. Exon Smith   }
17615cca6223SDuncan P. N. Exon Smith 
17625cca6223SDuncan P. N. Exon Smith   // Try to load the module from the prebuilt module path.
17635cca6223SDuncan P. N. Exon Smith   const HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
17645cca6223SDuncan P. N. Exon Smith   if (!HSOpts.PrebuiltModuleFiles.empty() ||
17655cca6223SDuncan P. N. Exon Smith       !HSOpts.PrebuiltModulePaths.empty()) {
17665cca6223SDuncan P. N. Exon Smith     ModuleFilename = HS.getPrebuiltModuleFileName(ModuleName);
176758c586e7SAlexandre Rames     if (HSOpts.EnablePrebuiltImplicitModules && ModuleFilename.empty())
176858c586e7SAlexandre Rames       ModuleFilename = HS.getPrebuiltImplicitModuleFileName(M);
17695cca6223SDuncan P. N. Exon Smith     if (!ModuleFilename.empty())
17705cca6223SDuncan P. N. Exon Smith       return MS_PrebuiltModulePath;
17715cca6223SDuncan P. N. Exon Smith   }
17725cca6223SDuncan P. N. Exon Smith 
17735cca6223SDuncan P. N. Exon Smith   // Try to load the module from the module cache.
17745cca6223SDuncan P. N. Exon Smith   if (M) {
17755cca6223SDuncan P. N. Exon Smith     ModuleFilename = HS.getCachedModuleFileName(M);
17765cca6223SDuncan P. N. Exon Smith     return MS_ModuleCache;
17775cca6223SDuncan P. N. Exon Smith   }
17785cca6223SDuncan P. N. Exon Smith 
17795cca6223SDuncan P. N. Exon Smith   return MS_ModuleNotFound;
17805cca6223SDuncan P. N. Exon Smith }
17815cca6223SDuncan P. N. Exon Smith 
findOrCompileModuleAndReadAST(StringRef ModuleName,SourceLocation ImportLoc,SourceLocation ModuleNameLoc,bool IsInclusionDirective)17825cca6223SDuncan P. N. Exon Smith ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(
17835cca6223SDuncan P. N. Exon Smith     StringRef ModuleName, SourceLocation ImportLoc,
17845cca6223SDuncan P. N. Exon Smith     SourceLocation ModuleNameLoc, bool IsInclusionDirective) {
17855cca6223SDuncan P. N. Exon Smith   // Search for a module with the given name.
17865cca6223SDuncan P. N. Exon Smith   HeaderSearch &HS = PP->getHeaderSearchInfo();
1787638c673aSJan Svoboda   Module *M =
1788638c673aSJan Svoboda       HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective);
17895cca6223SDuncan P. N. Exon Smith 
17905cca6223SDuncan P. N. Exon Smith   // Select the source and filename for loading the named module.
17915cca6223SDuncan P. N. Exon Smith   std::string ModuleFilename;
17925cca6223SDuncan P. N. Exon Smith   ModuleSource Source =
17935cca6223SDuncan P. N. Exon Smith       selectModuleSource(M, ModuleName, ModuleFilename, BuiltModules, HS);
17945cca6223SDuncan P. N. Exon Smith   if (Source == MS_ModuleNotFound) {
17955cca6223SDuncan P. N. Exon Smith     // We can't find a module, error out here.
17965cca6223SDuncan P. N. Exon Smith     getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
17975cca6223SDuncan P. N. Exon Smith         << ModuleName << SourceRange(ImportLoc, ModuleNameLoc);
17987c2afd58SDuncan P. N. Exon Smith     return nullptr;
17995cca6223SDuncan P. N. Exon Smith   }
18005cca6223SDuncan P. N. Exon Smith   if (ModuleFilename.empty()) {
18015cca6223SDuncan P. N. Exon Smith     if (M && M->HasIncompatibleModuleFile) {
18025cca6223SDuncan P. N. Exon Smith       // We tried and failed to load a module file for this module. Fall
18035cca6223SDuncan P. N. Exon Smith       // back to textual inclusion for its headers.
18045cca6223SDuncan P. N. Exon Smith       return ModuleLoadResult::ConfigMismatch;
18055cca6223SDuncan P. N. Exon Smith     }
18065cca6223SDuncan P. N. Exon Smith 
18075cca6223SDuncan P. N. Exon Smith     getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled)
18085cca6223SDuncan P. N. Exon Smith         << ModuleName;
18097c2afd58SDuncan P. N. Exon Smith     return nullptr;
18105cca6223SDuncan P. N. Exon Smith   }
18115cca6223SDuncan P. N. Exon Smith 
18125cca6223SDuncan P. N. Exon Smith   // Create an ASTReader on demand.
181320d51b2fSDuncan P. N. Exon Smith   if (!getASTReader())
181420d51b2fSDuncan P. N. Exon Smith     createASTReader();
18155cca6223SDuncan P. N. Exon Smith 
18165cca6223SDuncan P. N. Exon Smith   // Time how long it takes to load the module.
18175cca6223SDuncan P. N. Exon Smith   llvm::Timer Timer;
18185cca6223SDuncan P. N. Exon Smith   if (FrontendTimerGroup)
18195cca6223SDuncan P. N. Exon Smith     Timer.init("loading." + ModuleFilename, "Loading " + ModuleFilename,
18205cca6223SDuncan P. N. Exon Smith                *FrontendTimerGroup);
18215cca6223SDuncan P. N. Exon Smith   llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr);
18225cca6223SDuncan P. N. Exon Smith   llvm::TimeTraceScope TimeScope("Module Load", ModuleName);
18235cca6223SDuncan P. N. Exon Smith 
18245cca6223SDuncan P. N. Exon Smith   // Try to load the module file. If we are not trying to load from the
18255cca6223SDuncan P. N. Exon Smith   // module cache, we don't know how to rebuild modules.
18265cca6223SDuncan P. N. Exon Smith   unsigned ARRFlags = Source == MS_ModuleCache
1827a8cb39baSArgyrios Kyrtzidis                           ? ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing |
1828a8cb39baSArgyrios Kyrtzidis                                 ASTReader::ARR_TreatModuleWithErrorsAsOutOfDate
18295cca6223SDuncan P. N. Exon Smith                           : Source == MS_PrebuiltModulePath
18305cca6223SDuncan P. N. Exon Smith                                 ? 0
18315cca6223SDuncan P. N. Exon Smith                                 : ASTReader::ARR_ConfigurationMismatch;
183220d51b2fSDuncan P. N. Exon Smith   switch (getASTReader()->ReadAST(ModuleFilename,
18335cca6223SDuncan P. N. Exon Smith                                   Source == MS_PrebuiltModulePath
18345cca6223SDuncan P. N. Exon Smith                                       ? serialization::MK_PrebuiltModule
183520d51b2fSDuncan P. N. Exon Smith                                       : Source == MS_ModuleBuildPragma
183620d51b2fSDuncan P. N. Exon Smith                                             ? serialization::MK_ExplicitModule
18375cca6223SDuncan P. N. Exon Smith                                             : serialization::MK_ImplicitModule,
18385cca6223SDuncan P. N. Exon Smith                                   ImportLoc, ARRFlags)) {
18395cca6223SDuncan P. N. Exon Smith   case ASTReader::Success: {
18405cca6223SDuncan P. N. Exon Smith     if (M)
18415cca6223SDuncan P. N. Exon Smith       return M;
18425cca6223SDuncan P. N. Exon Smith     assert(Source != MS_ModuleCache &&
18435cca6223SDuncan P. N. Exon Smith            "missing module, but file loaded from cache");
18445cca6223SDuncan P. N. Exon Smith 
18455cca6223SDuncan P. N. Exon Smith     // A prebuilt module is indexed as a ModuleFile; the Module does not exist
18465cca6223SDuncan P. N. Exon Smith     // until the first call to ReadAST.  Look it up now.
1847638c673aSJan Svoboda     M = HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective);
18485cca6223SDuncan P. N. Exon Smith 
18495cca6223SDuncan P. N. Exon Smith     // Check whether M refers to the file in the prebuilt module path.
18505cca6223SDuncan P. N. Exon Smith     if (M && M->getASTFile())
18515cca6223SDuncan P. N. Exon Smith       if (auto ModuleFile = FileMgr->getFile(ModuleFilename))
18525cca6223SDuncan P. N. Exon Smith         if (*ModuleFile == M->getASTFile())
18535cca6223SDuncan P. N. Exon Smith           return M;
18545cca6223SDuncan P. N. Exon Smith 
18555cca6223SDuncan P. N. Exon Smith     getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt)
18565cca6223SDuncan P. N. Exon Smith         << ModuleName;
18575cca6223SDuncan P. N. Exon Smith     return ModuleLoadResult();
18585cca6223SDuncan P. N. Exon Smith   }
18595cca6223SDuncan P. N. Exon Smith 
18605cca6223SDuncan P. N. Exon Smith   case ASTReader::OutOfDate:
18615cca6223SDuncan P. N. Exon Smith   case ASTReader::Missing:
18625cca6223SDuncan P. N. Exon Smith     // The most interesting case.
18635cca6223SDuncan P. N. Exon Smith     break;
18645cca6223SDuncan P. N. Exon Smith 
18655cca6223SDuncan P. N. Exon Smith   case ASTReader::ConfigurationMismatch:
18665cca6223SDuncan P. N. Exon Smith     if (Source == MS_PrebuiltModulePath)
18675cca6223SDuncan P. N. Exon Smith       // FIXME: We shouldn't be setting HadFatalFailure below if we only
18685cca6223SDuncan P. N. Exon Smith       // produce a warning here!
18695cca6223SDuncan P. N. Exon Smith       getDiagnostics().Report(SourceLocation(),
18705cca6223SDuncan P. N. Exon Smith                               diag::warn_module_config_mismatch)
18715cca6223SDuncan P. N. Exon Smith           << ModuleFilename;
18725cca6223SDuncan P. N. Exon Smith     // Fall through to error out.
18735cca6223SDuncan P. N. Exon Smith     LLVM_FALLTHROUGH;
18745cca6223SDuncan P. N. Exon Smith   case ASTReader::VersionMismatch:
18755cca6223SDuncan P. N. Exon Smith   case ASTReader::HadErrors:
18765cca6223SDuncan P. N. Exon Smith     ModuleLoader::HadFatalFailure = true;
18775cca6223SDuncan P. N. Exon Smith     // FIXME: The ASTReader will already have complained, but can we shoehorn
18785cca6223SDuncan P. N. Exon Smith     // that diagnostic information into a more useful form?
18795cca6223SDuncan P. N. Exon Smith     return ModuleLoadResult();
18805cca6223SDuncan P. N. Exon Smith 
18815cca6223SDuncan P. N. Exon Smith   case ASTReader::Failure:
18825cca6223SDuncan P. N. Exon Smith     ModuleLoader::HadFatalFailure = true;
18835cca6223SDuncan P. N. Exon Smith     return ModuleLoadResult();
18845cca6223SDuncan P. N. Exon Smith   }
18855cca6223SDuncan P. N. Exon Smith 
18865cca6223SDuncan P. N. Exon Smith   // ReadAST returned Missing or OutOfDate.
18875cca6223SDuncan P. N. Exon Smith   if (Source != MS_ModuleCache) {
18885cca6223SDuncan P. N. Exon Smith     // We don't know the desired configuration for this module and don't
18895cca6223SDuncan P. N. Exon Smith     // necessarily even have a module map. Since ReadAST already produces
18905cca6223SDuncan P. N. Exon Smith     // diagnostics for these two cases, we simply error out here.
18915cca6223SDuncan P. N. Exon Smith     return ModuleLoadResult();
18925cca6223SDuncan P. N. Exon Smith   }
18935cca6223SDuncan P. N. Exon Smith 
18945cca6223SDuncan P. N. Exon Smith   // The module file is missing or out-of-date. Build it.
18955cca6223SDuncan P. N. Exon Smith   assert(M && "missing module, but trying to compile for cache");
18965cca6223SDuncan P. N. Exon Smith 
18975cca6223SDuncan P. N. Exon Smith   // Check whether there is a cycle in the module graph.
18985cca6223SDuncan P. N. Exon Smith   ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack();
18995cca6223SDuncan P. N. Exon Smith   ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
19005cca6223SDuncan P. N. Exon Smith   for (; Pos != PosEnd; ++Pos) {
19015cca6223SDuncan P. N. Exon Smith     if (Pos->first == ModuleName)
19025cca6223SDuncan P. N. Exon Smith       break;
19035cca6223SDuncan P. N. Exon Smith   }
19045cca6223SDuncan P. N. Exon Smith 
19055cca6223SDuncan P. N. Exon Smith   if (Pos != PosEnd) {
19065cca6223SDuncan P. N. Exon Smith     SmallString<256> CyclePath;
19075cca6223SDuncan P. N. Exon Smith     for (; Pos != PosEnd; ++Pos) {
19085cca6223SDuncan P. N. Exon Smith       CyclePath += Pos->first;
19095cca6223SDuncan P. N. Exon Smith       CyclePath += " -> ";
19105cca6223SDuncan P. N. Exon Smith     }
19115cca6223SDuncan P. N. Exon Smith     CyclePath += ModuleName;
19125cca6223SDuncan P. N. Exon Smith 
19135cca6223SDuncan P. N. Exon Smith     getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle)
19145cca6223SDuncan P. N. Exon Smith         << ModuleName << CyclePath;
19157c2afd58SDuncan P. N. Exon Smith     return nullptr;
19165cca6223SDuncan P. N. Exon Smith   }
19175cca6223SDuncan P. N. Exon Smith 
19185cca6223SDuncan P. N. Exon Smith   // Check whether we have already attempted to build this module (but
19195cca6223SDuncan P. N. Exon Smith   // failed).
19205cca6223SDuncan P. N. Exon Smith   if (getPreprocessorOpts().FailedModules &&
19215cca6223SDuncan P. N. Exon Smith       getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) {
19225cca6223SDuncan P. N. Exon Smith     getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built)
19235cca6223SDuncan P. N. Exon Smith         << ModuleName << SourceRange(ImportLoc, ModuleNameLoc);
19247c2afd58SDuncan P. N. Exon Smith     return nullptr;
19255cca6223SDuncan P. N. Exon Smith   }
19265cca6223SDuncan P. N. Exon Smith 
19275cca6223SDuncan P. N. Exon Smith   // Try to compile and then read the AST.
1928b714f73dSDuncan P. N. Exon Smith   if (!compileModuleAndReadAST(*this, ImportLoc, ModuleNameLoc, M,
19295cca6223SDuncan P. N. Exon Smith                                ModuleFilename)) {
19305cca6223SDuncan P. N. Exon Smith     assert(getDiagnostics().hasErrorOccurred() &&
19315cca6223SDuncan P. N. Exon Smith            "undiagnosed error in compileModuleAndReadAST");
19325cca6223SDuncan P. N. Exon Smith     if (getPreprocessorOpts().FailedModules)
19335cca6223SDuncan P. N. Exon Smith       getPreprocessorOpts().FailedModules->addFailed(ModuleName);
19347c2afd58SDuncan P. N. Exon Smith     return nullptr;
19355cca6223SDuncan P. N. Exon Smith   }
19365cca6223SDuncan P. N. Exon Smith 
19375cca6223SDuncan P. N. Exon Smith   // Okay, we've rebuilt and now loaded the module.
19385cca6223SDuncan P. N. Exon Smith   return M;
19395cca6223SDuncan P. N. Exon Smith }
19405cca6223SDuncan P. N. Exon Smith 
1941e842a474SRichard Smith ModuleLoadResult
loadModule(SourceLocation ImportLoc,ModuleIdPath Path,Module::NameVisibilityKind Visibility,bool IsInclusionDirective)19427a626570SDouglas Gregor CompilerInstance::loadModule(SourceLocation ImportLoc,
1943ff2be53fSDouglas Gregor                              ModuleIdPath Path,
1944bcfc7d02SDouglas Gregor                              Module::NameVisibilityKind Visibility,
1945bcfc7d02SDouglas Gregor                              bool IsInclusionDirective) {
194692304e00SRichard Smith   // Determine what file we're searching from.
1947d6509cf2SRichard Smith   StringRef ModuleName = Path[0].first->getName();
194892304e00SRichard Smith   SourceLocation ModuleNameLoc = Path[0].second;
194992304e00SRichard Smith 
19501805b8a4SDouglas Gregor   // If we've already handled this import, just return the cached result.
19511805b8a4SDouglas Gregor   // This one-element cache is important to eliminate redundant diagnostics
19521805b8a4SDouglas Gregor   // when both the preprocessor and parser see the same import declaration.
19538b563665SYaron Keren   if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) {
1954ff2be53fSDouglas Gregor     // Make the named module visible.
19557e82e019SRichard Smith     if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule)
195620d51b2fSDuncan P. N. Exon Smith       TheASTReader->makeModuleVisible(LastModuleImportResult, Visibility,
1957a7e2cc68SRichard Smith                                       ImportLoc);
195869021974SDouglas Gregor     return LastModuleImportResult;
1959ff2be53fSDouglas Gregor   }
19601805b8a4SDouglas Gregor 
19615196bc6bSDouglas Gregor   // If we don't already have information on this module, load the module now.
19628112a423SDuncan P. N. Exon Smith   Module *Module = nullptr;
196331e14f41SDuncan P. N. Exon Smith   ModuleMap &MM = getPreprocessor().getHeaderSearchInfo().getModuleMap();
19648112a423SDuncan P. N. Exon Smith   if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) {
19658112a423SDuncan P. N. Exon Smith     // Use the cached result, which may be nullptr.
19668112a423SDuncan P. N. Exon Smith     Module = *MaybeModule;
19677e82e019SRichard Smith   } else if (ModuleName == getLangOpts().CurrentModule) {
19682537a364SDouglas Gregor     // This is the module we're building.
196952431f39SBruno Cardoso Lopes     Module = PP->getHeaderSearchInfo().lookupModule(
1970638c673aSJan Svoboda         ModuleName, ImportLoc, /*AllowSearch*/ true,
197152431f39SBruno Cardoso Lopes         /*AllowExtraModuleMapSearch*/ !IsInclusionDirective);
1972d30446fdSBoris Kolpackov     /// FIXME: perhaps we should (a) look for a module using the module name
1973d30446fdSBoris Kolpackov     //  to file map (PrebuiltModuleFiles) and (b) diagnose if still not found?
1974d30446fdSBoris Kolpackov     //if (Module == nullptr) {
1975d30446fdSBoris Kolpackov     //  getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
1976d30446fdSBoris Kolpackov     //    << ModuleName;
197723e9146fSDuncan P. N. Exon Smith     //  DisableGeneratingGlobalModuleIndex = true;
1978d30446fdSBoris Kolpackov     //  return ModuleLoadResult();
1979d30446fdSBoris Kolpackov     //}
198031e14f41SDuncan P. N. Exon Smith     MM.cacheModuleLoad(*Path[0].first, Module);
19812537a364SDouglas Gregor   } else {
19825cca6223SDuncan P. N. Exon Smith     ModuleLoadResult Result = findOrCompileModuleAndReadAST(
19835cca6223SDuncan P. N. Exon Smith         ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective);
19845cca6223SDuncan P. N. Exon Smith     if (!Result.isNormal())
19855cca6223SDuncan P. N. Exon Smith       return Result;
19867c57a9bdSDuncan P. N. Exon Smith     if (!Result)
19877c57a9bdSDuncan P. N. Exon Smith       DisableGeneratingGlobalModuleIndex = true;
19885cca6223SDuncan P. N. Exon Smith     Module = Result;
198931e14f41SDuncan P. N. Exon Smith     MM.cacheModuleLoad(*Path[0].first, Module);
199069021974SDouglas Gregor   }
199169021974SDouglas Gregor 
19925cca6223SDuncan P. N. Exon Smith   // If we never found the module, fail.  Otherwise, verify the module and link
19935cca6223SDuncan P. N. Exon Smith   // it up.
199469021974SDouglas Gregor   if (!Module)
19957a626570SDouglas Gregor     return ModuleLoadResult();
199669021974SDouglas Gregor 
19975196bc6bSDouglas Gregor   // Verify that the rest of the module path actually corresponds to
19985196bc6bSDouglas Gregor   // a submodule.
199984bc0a27SBruno Cardoso Lopes   bool MapPrivateSubModToTopLevel = false;
20005196bc6bSDouglas Gregor   for (unsigned I = 1, N = Path.size(); I != N; ++I) {
20015196bc6bSDouglas Gregor     StringRef Name = Path[I].first->getName();
2002eb90e830SDouglas Gregor     clang::Module *Sub = Module->findSubmodule(Name);
20035196bc6bSDouglas Gregor 
20049284931eSBruno Cardoso Lopes     // If the user is requesting Foo.Private and it doesn't exist, try to
20059284931eSBruno Cardoso Lopes     // match Foo_Private and emit a warning asking for the user to write
20069284931eSBruno Cardoso Lopes     // @import Foo_Private instead. FIXME: remove this when existing clients
20079284931eSBruno Cardoso Lopes     // migrate off of Foo.Private syntax.
20089284931eSBruno Cardoso Lopes     if (!Sub && PP->getLangOpts().ImplicitModules && Name == "Private" &&
20099284931eSBruno Cardoso Lopes         Module == Module->getTopLevelModule()) {
20109284931eSBruno Cardoso Lopes       SmallString<128> PrivateModule(Module->Name);
20119284931eSBruno Cardoso Lopes       PrivateModule.append("_Private");
20129284931eSBruno Cardoso Lopes 
20139284931eSBruno Cardoso Lopes       SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> PrivPath;
20149284931eSBruno Cardoso Lopes       auto &II = PP->getIdentifierTable().get(
20159284931eSBruno Cardoso Lopes           PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID());
20169284931eSBruno Cardoso Lopes       PrivPath.push_back(std::make_pair(&II, Path[0].second));
20179284931eSBruno Cardoso Lopes 
2018ab6ef587SJan Svoboda       if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, ImportLoc, true,
2019ab6ef587SJan Svoboda                                                  !IsInclusionDirective))
2020ab6ef587SJan Svoboda         Sub = loadModule(ImportLoc, PrivPath, Visibility, IsInclusionDirective);
20219284931eSBruno Cardoso Lopes       if (Sub) {
20229284931eSBruno Cardoso Lopes         MapPrivateSubModToTopLevel = true;
20239284931eSBruno Cardoso Lopes         if (!getDiagnostics().isIgnored(
20249284931eSBruno Cardoso Lopes                 diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
20259284931eSBruno Cardoso Lopes           getDiagnostics().Report(Path[I].second,
20269284931eSBruno Cardoso Lopes                                   diag::warn_no_priv_submodule_use_toplevel)
20279284931eSBruno Cardoso Lopes               << Path[I].first << Module->getFullModuleName() << PrivateModule
20289284931eSBruno Cardoso Lopes               << SourceRange(Path[0].second, Path[I].second)
20299284931eSBruno Cardoso Lopes               << FixItHint::CreateReplacement(SourceRange(Path[0].second),
20309284931eSBruno Cardoso Lopes                                               PrivateModule);
20319284931eSBruno Cardoso Lopes           getDiagnostics().Report(Sub->DefinitionLoc,
20329284931eSBruno Cardoso Lopes                                   diag::note_private_top_level_defined);
20339284931eSBruno Cardoso Lopes         }
20349284931eSBruno Cardoso Lopes       }
20359284931eSBruno Cardoso Lopes     }
20369284931eSBruno Cardoso Lopes 
2037eb90e830SDouglas Gregor     if (!Sub) {
20385196bc6bSDouglas Gregor       // Attempt to perform typo correction to find a module name that works.
2039f857950dSDmitri Gribenko       SmallVector<StringRef, 2> Best;
20405196bc6bSDouglas Gregor       unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
20415196bc6bSDouglas Gregor 
2042c57ca335SJan Svoboda       for (class Module *SubModule : Module->submodules()) {
2043ab6ef587SJan Svoboda         unsigned ED =
2044ab6ef587SJan Svoboda             Name.edit_distance(SubModule->Name,
2045ab6ef587SJan Svoboda                                /*AllowReplacements=*/true, BestEditDistance);
20465196bc6bSDouglas Gregor         if (ED <= BestEditDistance) {
2047eb90e830SDouglas Gregor           if (ED < BestEditDistance) {
20485196bc6bSDouglas Gregor             Best.clear();
2049eb90e830SDouglas Gregor             BestEditDistance = ED;
2050eb90e830SDouglas Gregor           }
2051eb90e830SDouglas Gregor 
2052c57ca335SJan Svoboda           Best.push_back(SubModule->Name);
20535196bc6bSDouglas Gregor         }
20545196bc6bSDouglas Gregor       }
20555196bc6bSDouglas Gregor 
20565196bc6bSDouglas Gregor       // If there was a clear winner, user it.
20575196bc6bSDouglas Gregor       if (Best.size() == 1) {
2058ab6ef587SJan Svoboda         getDiagnostics().Report(Path[I].second, diag::err_no_submodule_suggest)
205969021974SDouglas Gregor             << Path[I].first << Module->getFullModuleName() << Best[0]
20605196bc6bSDouglas Gregor             << SourceRange(Path[0].second, Path[I - 1].second)
20615196bc6bSDouglas Gregor             << FixItHint::CreateReplacement(SourceRange(Path[I].second),
20625196bc6bSDouglas Gregor                                             Best[0]);
2063eb90e830SDouglas Gregor 
2064eb90e830SDouglas Gregor         Sub = Module->findSubmodule(Best[0]);
20655196bc6bSDouglas Gregor       }
20665196bc6bSDouglas Gregor     }
20675196bc6bSDouglas Gregor 
2068eb90e830SDouglas Gregor     if (!Sub) {
20695196bc6bSDouglas Gregor       // No submodule by this name. Complain, and don't look for further
20705196bc6bSDouglas Gregor       // submodules.
20715196bc6bSDouglas Gregor       getDiagnostics().Report(Path[I].second, diag::err_no_submodule)
207269021974SDouglas Gregor           << Path[I].first << Module->getFullModuleName()
20735196bc6bSDouglas Gregor           << SourceRange(Path[0].second, Path[I - 1].second);
20745196bc6bSDouglas Gregor       break;
20755196bc6bSDouglas Gregor     }
20765196bc6bSDouglas Gregor 
2077eb90e830SDouglas Gregor     Module = Sub;
20785196bc6bSDouglas Gregor   }
20795196bc6bSDouglas Gregor 
20802537a364SDouglas Gregor   // Make the named module visible, if it's not already part of the module
20812537a364SDouglas Gregor   // we are parsing.
208298a52db8SDouglas Gregor   if (ModuleName != getLangOpts().CurrentModule) {
208384bc0a27SBruno Cardoso Lopes     if (!Module->IsFromModuleFile && !MapPrivateSubModToTopLevel) {
208498a52db8SDouglas Gregor       // We have an umbrella header or directory that doesn't actually include
208598a52db8SDouglas Gregor       // all of the headers within the directory it covers. Complain about
208698a52db8SDouglas Gregor       // this missing submodule and recover by forgetting that we ever saw
208798a52db8SDouglas Gregor       // this submodule.
208898a52db8SDouglas Gregor       // FIXME: Should we detect this at module load time? It seems fairly
208998a52db8SDouglas Gregor       // expensive (and rare).
209098a52db8SDouglas Gregor       getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule)
209198a52db8SDouglas Gregor         << Module->getFullModuleName()
209298a52db8SDouglas Gregor         << SourceRange(Path.front().second, Path.back().second);
209398a52db8SDouglas Gregor 
2094a114c46eSRichard Smith       return ModuleLoadResult::MissingExpected;
209598a52db8SDouglas Gregor     }
20961fb5c3a6SDouglas Gregor 
20971fb5c3a6SDouglas Gregor     // Check whether this module is available.
209827e5aa08SRichard Smith     if (Preprocessor::checkModuleIsAvailable(getLangOpts(), getTarget(),
209927e5aa08SRichard Smith                                              getDiagnostics(), Module)) {
210027e5aa08SRichard Smith       getDiagnostics().Report(ImportLoc, diag::note_module_import_here)
21011fb5c3a6SDouglas Gregor         << SourceRange(Path.front().second, Path.back().second);
21021fb5c3a6SDouglas Gregor       LastModuleImportLoc = ImportLoc;
21037a626570SDouglas Gregor       LastModuleImportResult = ModuleLoadResult();
21047a626570SDouglas Gregor       return ModuleLoadResult();
21051fb5c3a6SDouglas Gregor     }
21061fb5c3a6SDouglas Gregor 
210720d51b2fSDuncan P. N. Exon Smith     TheASTReader->makeModuleVisible(Module, Visibility, ImportLoc);
210898a52db8SDouglas Gregor   }
21095196bc6bSDouglas Gregor 
211035b13eceSDouglas Gregor   // Check for any configuration macros that have changed.
211135b13eceSDouglas Gregor   clang::Module *TopModule = Module->getTopLevelModule();
211235b13eceSDouglas Gregor   for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) {
211335b13eceSDouglas Gregor     checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I],
211435b13eceSDouglas Gregor                      Module, ImportLoc);
211535b13eceSDouglas Gregor   }
211635b13eceSDouglas Gregor 
2117a3b5f71eSBruno Cardoso Lopes   // Resolve any remaining module using export_as for this one.
2118a3b5f71eSBruno Cardoso Lopes   getPreprocessor()
2119a3b5f71eSBruno Cardoso Lopes       .getHeaderSearchInfo()
2120a3b5f71eSBruno Cardoso Lopes       .getModuleMap()
2121a3b5f71eSBruno Cardoso Lopes       .resolveLinkAsDependencies(TopModule);
2122a3b5f71eSBruno Cardoso Lopes 
21231805b8a4SDouglas Gregor   LastModuleImportLoc = ImportLoc;
2124a114c46eSRichard Smith   LastModuleImportResult = ModuleLoadResult(Module);
21257a626570SDouglas Gregor   return LastModuleImportResult;
212608142534SDouglas Gregor }
2127c147b0bcSDouglas Gregor 
createModuleFromSource(SourceLocation ImportLoc,StringRef ModuleName,StringRef Source)21285cca6223SDuncan P. N. Exon Smith void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc,
21295d2ed489SRichard Smith                                               StringRef ModuleName,
21305d2ed489SRichard Smith                                               StringRef Source) {
21319565c75bSRichard Smith   // Avoid creating filenames with special characters.
21329565c75bSRichard Smith   SmallString<128> CleanModuleName(ModuleName);
21339565c75bSRichard Smith   for (auto &C : CleanModuleName)
21349565c75bSRichard Smith     if (!isAlphanumeric(C))
21359565c75bSRichard Smith       C = '_';
21369565c75bSRichard Smith 
21375d2ed489SRichard Smith   // FIXME: Using a randomized filename here means that our intermediate .pcm
21385d2ed489SRichard Smith   // output is nondeterministic (as .pcm files refer to each other by name).
21395d2ed489SRichard Smith   // Can this affect the output in any way?
21405d2ed489SRichard Smith   SmallString<128> ModuleFileName;
21415d2ed489SRichard Smith   if (std::error_code EC = llvm::sys::fs::createTemporaryFile(
21429565c75bSRichard Smith           CleanModuleName, "pcm", ModuleFileName)) {
21435d2ed489SRichard Smith     getDiagnostics().Report(ImportLoc, diag::err_fe_unable_to_open_output)
21445d2ed489SRichard Smith         << ModuleFileName << EC.message();
21455d2ed489SRichard Smith     return;
21465d2ed489SRichard Smith   }
21479565c75bSRichard Smith   std::string ModuleMapFileName = (CleanModuleName + ".map").str();
21485d2ed489SRichard Smith 
21495d2ed489SRichard Smith   FrontendInputFile Input(
21505d2ed489SRichard Smith       ModuleMapFileName,
21515d2ed489SRichard Smith       InputKind(getLanguageFromOptions(*Invocation->getLangOpts()),
21525d2ed489SRichard Smith                 InputKind::ModuleMap, /*Preprocessed*/true));
21535d2ed489SRichard Smith 
21545d2ed489SRichard Smith   std::string NullTerminatedSource(Source.str());
21555d2ed489SRichard Smith 
21565d2ed489SRichard Smith   auto PreBuildStep = [&](CompilerInstance &Other) {
21575d2ed489SRichard Smith     // Create a virtual file containing our desired source.
21585d2ed489SRichard Smith     // FIXME: We shouldn't need to do this.
21595d2ed489SRichard Smith     const FileEntry *ModuleMapFile = Other.getFileManager().getVirtualFile(
21605d2ed489SRichard Smith         ModuleMapFileName, NullTerminatedSource.size(), 0);
21615d2ed489SRichard Smith     Other.getSourceManager().overrideFileContents(
2162b8debabbSKazu Hirata         ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource));
21635d2ed489SRichard Smith 
21645d2ed489SRichard Smith     Other.BuiltModules = std::move(BuiltModules);
216586a3ef5bSRichard Smith     Other.DeleteBuiltModules = false;
21665d2ed489SRichard Smith   };
21675d2ed489SRichard Smith 
21685d2ed489SRichard Smith   auto PostBuildStep = [this](CompilerInstance &Other) {
21695d2ed489SRichard Smith     BuiltModules = std::move(Other.BuiltModules);
21705d2ed489SRichard Smith   };
21715d2ed489SRichard Smith 
21725d2ed489SRichard Smith   // Build the module, inheriting any modules that we've built locally.
21735d2ed489SRichard Smith   if (compileModuleImpl(*this, ImportLoc, ModuleName, Input, StringRef(),
21745d2ed489SRichard Smith                         ModuleFileName, PreBuildStep, PostBuildStep)) {
2175adcd0268SBenjamin Kramer     BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName.str());
21765d2ed489SRichard Smith     llvm::sys::RemoveFileOnSignal(ModuleFileName);
21775d2ed489SRichard Smith   }
21785d2ed489SRichard Smith }
21795d2ed489SRichard Smith 
makeModuleVisible(Module * Mod,Module::NameVisibilityKind Visibility,SourceLocation ImportLoc)2180c147b0bcSDouglas Gregor void CompilerInstance::makeModuleVisible(Module *Mod,
2181125df058SArgyrios Kyrtzidis                                          Module::NameVisibilityKind Visibility,
2182a7e2cc68SRichard Smith                                          SourceLocation ImportLoc) {
218320d51b2fSDuncan P. N. Exon Smith   if (!TheASTReader)
218420d51b2fSDuncan P. N. Exon Smith     createASTReader();
218520d51b2fSDuncan P. N. Exon Smith   if (!TheASTReader)
218642413141SRichard Smith     return;
218742413141SRichard Smith 
218820d51b2fSDuncan P. N. Exon Smith   TheASTReader->makeModuleVisible(Mod, Visibility, ImportLoc);
2189c147b0bcSDouglas Gregor }
2190c147b0bcSDouglas Gregor 
loadGlobalModuleIndex(SourceLocation TriggerLoc)21912255f2ceSJohn Thompson GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
21922255f2ceSJohn Thompson     SourceLocation TriggerLoc) {
21933938f0c7SRichard Smith   if (getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty())
21943938f0c7SRichard Smith     return nullptr;
219520d51b2fSDuncan P. N. Exon Smith   if (!TheASTReader)
219620d51b2fSDuncan P. N. Exon Smith     createASTReader();
21972255f2ceSJohn Thompson   // Can't do anything if we don't have the module manager.
219820d51b2fSDuncan P. N. Exon Smith   if (!TheASTReader)
219949a2790fSCraig Topper     return nullptr;
22002255f2ceSJohn Thompson   // Get an existing global index.  This loads it if not already
22012255f2ceSJohn Thompson   // loaded.
220220d51b2fSDuncan P. N. Exon Smith   TheASTReader->loadGlobalIndex();
220320d51b2fSDuncan P. N. Exon Smith   GlobalModuleIndex *GlobalIndex = TheASTReader->getGlobalIndex();
22042255f2ceSJohn Thompson   // If the global index doesn't exist, create it.
22052255f2ceSJohn Thompson   if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() &&
22062255f2ceSJohn Thompson       hasPreprocessor()) {
22072255f2ceSJohn Thompson     llvm::sys::fs::create_directories(
22082255f2ceSJohn Thompson       getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
22090e828958SJF Bastien     if (llvm::Error Err = GlobalModuleIndex::writeIndex(
2210fb2398d0SAdrian Prantl             getFileManager(), getPCHContainerReader(),
22110e828958SJF Bastien             getPreprocessor().getHeaderSearchInfo().getModuleCachePath())) {
22120e828958SJF Bastien       // FIXME this drops the error on the floor. This code is only used for
22130e828958SJF Bastien       // typo correction and drops more than just this one source of errors
22140e828958SJF Bastien       // (such as the directory creation failure above). It should handle the
22150e828958SJF Bastien       // error.
22160e828958SJF Bastien       consumeError(std::move(Err));
22170e828958SJF Bastien       return nullptr;
22180e828958SJF Bastien     }
221920d51b2fSDuncan P. N. Exon Smith     TheASTReader->resetForReload();
222020d51b2fSDuncan P. N. Exon Smith     TheASTReader->loadGlobalIndex();
222120d51b2fSDuncan P. N. Exon Smith     GlobalIndex = TheASTReader->getGlobalIndex();
22222255f2ceSJohn Thompson   }
22232255f2ceSJohn Thompson   // For finding modules needing to be imported for fixit messages,
22242255f2ceSJohn Thompson   // we need to make the global index cover all modules, so we do that here.
22252255f2ceSJohn Thompson   if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) {
22262255f2ceSJohn Thompson     ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap();
22272255f2ceSJohn Thompson     bool RecreateIndex = false;
22282255f2ceSJohn Thompson     for (ModuleMap::module_iterator I = MMap.module_begin(),
22292255f2ceSJohn Thompson         E = MMap.module_end(); I != E; ++I) {
22302255f2ceSJohn Thompson       Module *TheModule = I->second;
22312255f2ceSJohn Thompson       const FileEntry *Entry = TheModule->getASTFile();
22322255f2ceSJohn Thompson       if (!Entry) {
22332255f2ceSJohn Thompson         SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
22342255f2ceSJohn Thompson         Path.push_back(std::make_pair(
22352255f2ceSJohn Thompson             getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc));
22362255f2ceSJohn Thompson         std::reverse(Path.begin(), Path.end());
22372255f2ceSJohn Thompson         // Load a module as hidden.  This also adds it to the global index.
2238629d8e6fSRichard Smith         loadModule(TheModule->DefinitionLoc, Path, Module::Hidden, false);
22392255f2ceSJohn Thompson         RecreateIndex = true;
22402255f2ceSJohn Thompson       }
22412255f2ceSJohn Thompson     }
22422255f2ceSJohn Thompson     if (RecreateIndex) {
22430e828958SJF Bastien       if (llvm::Error Err = GlobalModuleIndex::writeIndex(
2244fb2398d0SAdrian Prantl               getFileManager(), getPCHContainerReader(),
22450e828958SJF Bastien               getPreprocessor().getHeaderSearchInfo().getModuleCachePath())) {
22460e828958SJF Bastien         // FIXME As above, this drops the error on the floor.
22470e828958SJF Bastien         consumeError(std::move(Err));
22480e828958SJF Bastien         return nullptr;
22490e828958SJF Bastien       }
225020d51b2fSDuncan P. N. Exon Smith       TheASTReader->resetForReload();
225120d51b2fSDuncan P. N. Exon Smith       TheASTReader->loadGlobalIndex();
225220d51b2fSDuncan P. N. Exon Smith       GlobalIndex = TheASTReader->getGlobalIndex();
22532255f2ceSJohn Thompson     }
22542255f2ceSJohn Thompson     HaveFullGlobalModuleIndex = true;
22552255f2ceSJohn Thompson   }
22562255f2ceSJohn Thompson   return GlobalIndex;
22572255f2ceSJohn Thompson }
22582d94bbb0SJohn Thompson 
22592d94bbb0SJohn Thompson // Check global module index for missing imports.
22602d94bbb0SJohn Thompson bool
lookupMissingImports(StringRef Name,SourceLocation TriggerLoc)22612d94bbb0SJohn Thompson CompilerInstance::lookupMissingImports(StringRef Name,
22622d94bbb0SJohn Thompson                                        SourceLocation TriggerLoc) {
22632d94bbb0SJohn Thompson   // Look for the symbol in non-imported modules, but only if an error
22642d94bbb0SJohn Thompson   // actually occurred.
22652d94bbb0SJohn Thompson   if (!buildingModule()) {
22662d94bbb0SJohn Thompson     // Load global module index, or retrieve a previously loaded one.
22672d94bbb0SJohn Thompson     GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex(
22682d94bbb0SJohn Thompson       TriggerLoc);
22692d94bbb0SJohn Thompson 
22702d94bbb0SJohn Thompson     // Only if we have a global index.
22712d94bbb0SJohn Thompson     if (GlobalIndex) {
22722d94bbb0SJohn Thompson       GlobalModuleIndex::HitSet FoundModules;
22732d94bbb0SJohn Thompson 
22742d94bbb0SJohn Thompson       // Find the modules that reference the identifier.
22752d94bbb0SJohn Thompson       // Note that this only finds top-level modules.
22762d94bbb0SJohn Thompson       // We'll let diagnoseTypo find the actual declaration module.
22772d94bbb0SJohn Thompson       if (GlobalIndex->lookupIdentifier(Name, FoundModules))
22782d94bbb0SJohn Thompson         return true;
22792d94bbb0SJohn Thompson     }
22802d94bbb0SJohn Thompson   }
22812d94bbb0SJohn Thompson 
22822d94bbb0SJohn Thompson   return false;
22832d94bbb0SJohn Thompson }
resetAndLeakSema()22849941da41SDavid Blaikie void CompilerInstance::resetAndLeakSema() { llvm::BuryPointer(takeSema()); }
22857de9969bSBenjamin Kramer 
setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS)22867de9969bSBenjamin Kramer void CompilerInstance::setExternalSemaSource(
22877de9969bSBenjamin Kramer     IntrusiveRefCntPtr<ExternalSemaSource> ESS) {
22887de9969bSBenjamin Kramer   ExternalSemaSrc = std::move(ESS);
22897de9969bSBenjamin Kramer }
2290