1f4a2713aSLionel Sambuc //===--- CompilerInstance.cpp ---------------------------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc
10f4a2713aSLionel Sambuc #include "clang/Frontend/CompilerInstance.h"
11f4a2713aSLionel Sambuc #include "clang/AST/ASTConsumer.h"
12f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
13f4a2713aSLionel Sambuc #include "clang/AST/Decl.h"
14f4a2713aSLionel Sambuc #include "clang/Basic/Diagnostic.h"
15f4a2713aSLionel Sambuc #include "clang/Basic/FileManager.h"
16f4a2713aSLionel Sambuc #include "clang/Basic/SourceManager.h"
17f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h"
18f4a2713aSLionel Sambuc #include "clang/Basic/Version.h"
19*0a6a1f1dSLionel Sambuc #include "clang/Config/config.h"
20f4a2713aSLionel Sambuc #include "clang/Frontend/ChainedDiagnosticConsumer.h"
21f4a2713aSLionel Sambuc #include "clang/Frontend/FrontendAction.h"
22f4a2713aSLionel Sambuc #include "clang/Frontend/FrontendActions.h"
23f4a2713aSLionel Sambuc #include "clang/Frontend/FrontendDiagnostic.h"
24f4a2713aSLionel Sambuc #include "clang/Frontend/LogDiagnosticPrinter.h"
25f4a2713aSLionel Sambuc #include "clang/Frontend/SerializedDiagnosticPrinter.h"
26f4a2713aSLionel Sambuc #include "clang/Frontend/TextDiagnosticPrinter.h"
27f4a2713aSLionel Sambuc #include "clang/Frontend/Utils.h"
28f4a2713aSLionel Sambuc #include "clang/Frontend/VerifyDiagnosticConsumer.h"
29f4a2713aSLionel Sambuc #include "clang/Lex/HeaderSearch.h"
30f4a2713aSLionel Sambuc #include "clang/Lex/PTHManager.h"
31f4a2713aSLionel Sambuc #include "clang/Lex/Preprocessor.h"
32f4a2713aSLionel Sambuc #include "clang/Sema/CodeCompleteConsumer.h"
33f4a2713aSLionel Sambuc #include "clang/Sema/Sema.h"
34f4a2713aSLionel Sambuc #include "clang/Serialization/ASTReader.h"
35*0a6a1f1dSLionel Sambuc #include "clang/Serialization/GlobalModuleIndex.h"
36f4a2713aSLionel Sambuc #include "llvm/ADT/Statistic.h"
37f4a2713aSLionel Sambuc #include "llvm/Support/CrashRecoveryContext.h"
38*0a6a1f1dSLionel Sambuc #include "llvm/Support/Errc.h"
39f4a2713aSLionel Sambuc #include "llvm/Support/FileSystem.h"
40f4a2713aSLionel Sambuc #include "llvm/Support/Host.h"
41f4a2713aSLionel Sambuc #include "llvm/Support/LockFileManager.h"
42f4a2713aSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
43f4a2713aSLionel Sambuc #include "llvm/Support/Path.h"
44f4a2713aSLionel Sambuc #include "llvm/Support/Program.h"
45f4a2713aSLionel Sambuc #include "llvm/Support/Signals.h"
46f4a2713aSLionel Sambuc #include "llvm/Support/Timer.h"
47f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
48f4a2713aSLionel Sambuc #include <sys/stat.h>
49*0a6a1f1dSLionel Sambuc #include <system_error>
50f4a2713aSLionel Sambuc #include <time.h>
51f4a2713aSLionel Sambuc
52f4a2713aSLionel Sambuc using namespace clang;
53f4a2713aSLionel Sambuc
CompilerInstance(bool BuildingModule)54*0a6a1f1dSLionel Sambuc CompilerInstance::CompilerInstance(bool BuildingModule)
55*0a6a1f1dSLionel Sambuc : ModuleLoader(BuildingModule),
56*0a6a1f1dSLionel Sambuc Invocation(new CompilerInvocation()), ModuleManager(nullptr),
57*0a6a1f1dSLionel Sambuc BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false),
58*0a6a1f1dSLionel Sambuc ModuleBuildFailed(false) {
59f4a2713aSLionel Sambuc }
60f4a2713aSLionel Sambuc
~CompilerInstance()61f4a2713aSLionel Sambuc CompilerInstance::~CompilerInstance() {
62f4a2713aSLionel Sambuc assert(OutputFiles.empty() && "Still output files in flight?");
63f4a2713aSLionel Sambuc }
64f4a2713aSLionel Sambuc
setInvocation(CompilerInvocation * Value)65f4a2713aSLionel Sambuc void CompilerInstance::setInvocation(CompilerInvocation *Value) {
66f4a2713aSLionel Sambuc Invocation = Value;
67f4a2713aSLionel Sambuc }
68f4a2713aSLionel Sambuc
shouldBuildGlobalModuleIndex() const69f4a2713aSLionel Sambuc bool CompilerInstance::shouldBuildGlobalModuleIndex() const {
70f4a2713aSLionel Sambuc return (BuildGlobalModuleIndex ||
71f4a2713aSLionel Sambuc (ModuleManager && ModuleManager->isGlobalIndexUnavailable() &&
72f4a2713aSLionel Sambuc getFrontendOpts().GenerateGlobalModuleIndex)) &&
73f4a2713aSLionel Sambuc !ModuleBuildFailed;
74f4a2713aSLionel Sambuc }
75f4a2713aSLionel Sambuc
setDiagnostics(DiagnosticsEngine * Value)76f4a2713aSLionel Sambuc void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) {
77f4a2713aSLionel Sambuc Diagnostics = Value;
78f4a2713aSLionel Sambuc }
79f4a2713aSLionel Sambuc
setTarget(TargetInfo * Value)80f4a2713aSLionel Sambuc void CompilerInstance::setTarget(TargetInfo *Value) {
81f4a2713aSLionel Sambuc Target = Value;
82f4a2713aSLionel Sambuc }
83f4a2713aSLionel Sambuc
setFileManager(FileManager * Value)84f4a2713aSLionel Sambuc void CompilerInstance::setFileManager(FileManager *Value) {
85f4a2713aSLionel Sambuc FileMgr = Value;
86*0a6a1f1dSLionel Sambuc if (Value)
87*0a6a1f1dSLionel Sambuc VirtualFileSystem = Value->getVirtualFileSystem();
88*0a6a1f1dSLionel Sambuc else
89*0a6a1f1dSLionel Sambuc VirtualFileSystem.reset();
90f4a2713aSLionel Sambuc }
91f4a2713aSLionel Sambuc
setSourceManager(SourceManager * Value)92f4a2713aSLionel Sambuc void CompilerInstance::setSourceManager(SourceManager *Value) {
93f4a2713aSLionel Sambuc SourceMgr = Value;
94f4a2713aSLionel Sambuc }
95f4a2713aSLionel Sambuc
setPreprocessor(Preprocessor * Value)96f4a2713aSLionel Sambuc void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; }
97f4a2713aSLionel Sambuc
setASTContext(ASTContext * Value)98f4a2713aSLionel Sambuc void CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; }
99f4a2713aSLionel Sambuc
setSema(Sema * S)100f4a2713aSLionel Sambuc void CompilerInstance::setSema(Sema *S) {
101f4a2713aSLionel Sambuc TheSema.reset(S);
102f4a2713aSLionel Sambuc }
103f4a2713aSLionel Sambuc
setASTConsumer(std::unique_ptr<ASTConsumer> Value)104*0a6a1f1dSLionel Sambuc void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) {
105*0a6a1f1dSLionel Sambuc Consumer = std::move(Value);
106f4a2713aSLionel Sambuc }
107f4a2713aSLionel Sambuc
setCodeCompletionConsumer(CodeCompleteConsumer * Value)108f4a2713aSLionel Sambuc void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
109f4a2713aSLionel Sambuc CompletionConsumer.reset(Value);
110f4a2713aSLionel Sambuc }
111f4a2713aSLionel Sambuc
takeSema()112*0a6a1f1dSLionel Sambuc std::unique_ptr<Sema> CompilerInstance::takeSema() {
113*0a6a1f1dSLionel Sambuc return std::move(TheSema);
114*0a6a1f1dSLionel Sambuc }
115*0a6a1f1dSLionel Sambuc
getModuleManager() const116*0a6a1f1dSLionel Sambuc IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const {
117*0a6a1f1dSLionel Sambuc return ModuleManager;
118*0a6a1f1dSLionel Sambuc }
setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader)119*0a6a1f1dSLionel Sambuc void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) {
120*0a6a1f1dSLionel Sambuc ModuleManager = Reader;
121*0a6a1f1dSLionel Sambuc }
122*0a6a1f1dSLionel Sambuc
123*0a6a1f1dSLionel Sambuc std::shared_ptr<ModuleDependencyCollector>
getModuleDepCollector() const124*0a6a1f1dSLionel Sambuc CompilerInstance::getModuleDepCollector() const {
125*0a6a1f1dSLionel Sambuc return ModuleDepCollector;
126*0a6a1f1dSLionel Sambuc }
127*0a6a1f1dSLionel Sambuc
setModuleDepCollector(std::shared_ptr<ModuleDependencyCollector> Collector)128*0a6a1f1dSLionel Sambuc void CompilerInstance::setModuleDepCollector(
129*0a6a1f1dSLionel Sambuc std::shared_ptr<ModuleDependencyCollector> Collector) {
130*0a6a1f1dSLionel Sambuc ModuleDepCollector = Collector;
131*0a6a1f1dSLionel Sambuc }
132*0a6a1f1dSLionel Sambuc
133f4a2713aSLionel Sambuc // Diagnostics
SetUpDiagnosticLog(DiagnosticOptions * DiagOpts,const CodeGenOptions * CodeGenOpts,DiagnosticsEngine & Diags)134f4a2713aSLionel Sambuc static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
135f4a2713aSLionel Sambuc const CodeGenOptions *CodeGenOpts,
136f4a2713aSLionel Sambuc DiagnosticsEngine &Diags) {
137*0a6a1f1dSLionel Sambuc std::error_code EC;
138*0a6a1f1dSLionel Sambuc std::unique_ptr<raw_ostream> StreamOwner;
139f4a2713aSLionel Sambuc raw_ostream *OS = &llvm::errs();
140f4a2713aSLionel Sambuc if (DiagOpts->DiagnosticLogFile != "-") {
141f4a2713aSLionel Sambuc // Create the output stream.
142*0a6a1f1dSLionel Sambuc auto FileOS = llvm::make_unique<llvm::raw_fd_ostream>(
143*0a6a1f1dSLionel Sambuc DiagOpts->DiagnosticLogFile, EC,
144*0a6a1f1dSLionel Sambuc llvm::sys::fs::F_Append | llvm::sys::fs::F_Text);
145*0a6a1f1dSLionel Sambuc if (EC) {
146f4a2713aSLionel Sambuc Diags.Report(diag::warn_fe_cc_log_diagnostics_failure)
147*0a6a1f1dSLionel Sambuc << DiagOpts->DiagnosticLogFile << EC.message();
148f4a2713aSLionel Sambuc } else {
149f4a2713aSLionel Sambuc FileOS->SetUnbuffered();
150f4a2713aSLionel Sambuc FileOS->SetUseAtomicWrites(true);
151*0a6a1f1dSLionel Sambuc OS = FileOS.get();
152*0a6a1f1dSLionel Sambuc StreamOwner = std::move(FileOS);
153f4a2713aSLionel Sambuc }
154f4a2713aSLionel Sambuc }
155f4a2713aSLionel Sambuc
156f4a2713aSLionel Sambuc // Chain in the diagnostic client which will log the diagnostics.
157*0a6a1f1dSLionel Sambuc auto Logger = llvm::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,
158*0a6a1f1dSLionel Sambuc std::move(StreamOwner));
159f4a2713aSLionel Sambuc if (CodeGenOpts)
160f4a2713aSLionel Sambuc Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags);
161*0a6a1f1dSLionel Sambuc assert(Diags.ownsClient());
162*0a6a1f1dSLionel Sambuc Diags.setClient(
163*0a6a1f1dSLionel Sambuc new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger)));
164f4a2713aSLionel Sambuc }
165f4a2713aSLionel Sambuc
SetupSerializedDiagnostics(DiagnosticOptions * DiagOpts,DiagnosticsEngine & Diags,StringRef OutputFile)166f4a2713aSLionel Sambuc static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts,
167f4a2713aSLionel Sambuc DiagnosticsEngine &Diags,
168f4a2713aSLionel Sambuc StringRef OutputFile) {
169*0a6a1f1dSLionel Sambuc auto SerializedConsumer =
170*0a6a1f1dSLionel Sambuc clang::serialized_diags::create(OutputFile, DiagOpts);
171f4a2713aSLionel Sambuc
172*0a6a1f1dSLionel Sambuc if (Diags.ownsClient()) {
173*0a6a1f1dSLionel Sambuc Diags.setClient(new ChainedDiagnosticConsumer(
174*0a6a1f1dSLionel Sambuc Diags.takeClient(), std::move(SerializedConsumer)));
175*0a6a1f1dSLionel Sambuc } else {
176*0a6a1f1dSLionel Sambuc Diags.setClient(new ChainedDiagnosticConsumer(
177*0a6a1f1dSLionel Sambuc Diags.getClient(), std::move(SerializedConsumer)));
178f4a2713aSLionel Sambuc }
179f4a2713aSLionel Sambuc }
180f4a2713aSLionel Sambuc
createDiagnostics(DiagnosticConsumer * Client,bool ShouldOwnClient)181f4a2713aSLionel Sambuc void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client,
182f4a2713aSLionel Sambuc bool ShouldOwnClient) {
183f4a2713aSLionel Sambuc Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client,
184f4a2713aSLionel Sambuc ShouldOwnClient, &getCodeGenOpts());
185f4a2713aSLionel Sambuc }
186f4a2713aSLionel Sambuc
187f4a2713aSLionel Sambuc IntrusiveRefCntPtr<DiagnosticsEngine>
createDiagnostics(DiagnosticOptions * Opts,DiagnosticConsumer * Client,bool ShouldOwnClient,const CodeGenOptions * CodeGenOpts)188f4a2713aSLionel Sambuc CompilerInstance::createDiagnostics(DiagnosticOptions *Opts,
189f4a2713aSLionel Sambuc DiagnosticConsumer *Client,
190f4a2713aSLionel Sambuc bool ShouldOwnClient,
191f4a2713aSLionel Sambuc const CodeGenOptions *CodeGenOpts) {
192f4a2713aSLionel Sambuc IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
193f4a2713aSLionel Sambuc IntrusiveRefCntPtr<DiagnosticsEngine>
194f4a2713aSLionel Sambuc Diags(new DiagnosticsEngine(DiagID, Opts));
195f4a2713aSLionel Sambuc
196f4a2713aSLionel Sambuc // Create the diagnostic client for reporting errors or for
197f4a2713aSLionel Sambuc // implementing -verify.
198f4a2713aSLionel Sambuc if (Client) {
199f4a2713aSLionel Sambuc Diags->setClient(Client, ShouldOwnClient);
200f4a2713aSLionel Sambuc } else
201f4a2713aSLionel Sambuc Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));
202f4a2713aSLionel Sambuc
203f4a2713aSLionel Sambuc // Chain in -verify checker, if requested.
204f4a2713aSLionel Sambuc if (Opts->VerifyDiagnostics)
205f4a2713aSLionel Sambuc Diags->setClient(new VerifyDiagnosticConsumer(*Diags));
206f4a2713aSLionel Sambuc
207f4a2713aSLionel Sambuc // Chain in -diagnostic-log-file dumper, if requested.
208f4a2713aSLionel Sambuc if (!Opts->DiagnosticLogFile.empty())
209f4a2713aSLionel Sambuc SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags);
210f4a2713aSLionel Sambuc
211f4a2713aSLionel Sambuc if (!Opts->DiagnosticSerializationFile.empty())
212f4a2713aSLionel Sambuc SetupSerializedDiagnostics(Opts, *Diags,
213f4a2713aSLionel Sambuc Opts->DiagnosticSerializationFile);
214f4a2713aSLionel Sambuc
215f4a2713aSLionel Sambuc // Configure our handling of diagnostics.
216f4a2713aSLionel Sambuc ProcessWarningOptions(*Diags, *Opts);
217f4a2713aSLionel Sambuc
218f4a2713aSLionel Sambuc return Diags;
219f4a2713aSLionel Sambuc }
220f4a2713aSLionel Sambuc
221f4a2713aSLionel Sambuc // File Manager
222f4a2713aSLionel Sambuc
createFileManager()223f4a2713aSLionel Sambuc void CompilerInstance::createFileManager() {
224*0a6a1f1dSLionel Sambuc if (!hasVirtualFileSystem()) {
225*0a6a1f1dSLionel Sambuc // TODO: choose the virtual file system based on the CompilerInvocation.
226*0a6a1f1dSLionel Sambuc setVirtualFileSystem(vfs::getRealFileSystem());
227*0a6a1f1dSLionel Sambuc }
228*0a6a1f1dSLionel Sambuc FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem);
229f4a2713aSLionel Sambuc }
230f4a2713aSLionel Sambuc
231f4a2713aSLionel Sambuc // Source Manager
232f4a2713aSLionel Sambuc
createSourceManager(FileManager & FileMgr)233f4a2713aSLionel Sambuc void CompilerInstance::createSourceManager(FileManager &FileMgr) {
234f4a2713aSLionel Sambuc SourceMgr = new SourceManager(getDiagnostics(), FileMgr);
235f4a2713aSLionel Sambuc }
236f4a2713aSLionel Sambuc
237*0a6a1f1dSLionel Sambuc // Initialize the remapping of files to alternative contents, e.g.,
238*0a6a1f1dSLionel Sambuc // those specified through other files.
InitializeFileRemapping(DiagnosticsEngine & Diags,SourceManager & SourceMgr,FileManager & FileMgr,const PreprocessorOptions & InitOpts)239*0a6a1f1dSLionel Sambuc static void InitializeFileRemapping(DiagnosticsEngine &Diags,
240*0a6a1f1dSLionel Sambuc SourceManager &SourceMgr,
241*0a6a1f1dSLionel Sambuc FileManager &FileMgr,
242*0a6a1f1dSLionel Sambuc const PreprocessorOptions &InitOpts) {
243*0a6a1f1dSLionel Sambuc // Remap files in the source manager (with buffers).
244*0a6a1f1dSLionel Sambuc for (const auto &RB : InitOpts.RemappedFileBuffers) {
245*0a6a1f1dSLionel Sambuc // Create the file entry for the file that we're mapping from.
246*0a6a1f1dSLionel Sambuc const FileEntry *FromFile =
247*0a6a1f1dSLionel Sambuc FileMgr.getVirtualFile(RB.first, RB.second->getBufferSize(), 0);
248*0a6a1f1dSLionel Sambuc if (!FromFile) {
249*0a6a1f1dSLionel Sambuc Diags.Report(diag::err_fe_remap_missing_from_file) << RB.first;
250*0a6a1f1dSLionel Sambuc if (!InitOpts.RetainRemappedFileBuffers)
251*0a6a1f1dSLionel Sambuc delete RB.second;
252*0a6a1f1dSLionel Sambuc continue;
253*0a6a1f1dSLionel Sambuc }
254*0a6a1f1dSLionel Sambuc
255*0a6a1f1dSLionel Sambuc // Override the contents of the "from" file with the contents of
256*0a6a1f1dSLionel Sambuc // the "to" file.
257*0a6a1f1dSLionel Sambuc SourceMgr.overrideFileContents(FromFile, RB.second,
258*0a6a1f1dSLionel Sambuc InitOpts.RetainRemappedFileBuffers);
259*0a6a1f1dSLionel Sambuc }
260*0a6a1f1dSLionel Sambuc
261*0a6a1f1dSLionel Sambuc // Remap files in the source manager (with other files).
262*0a6a1f1dSLionel Sambuc for (const auto &RF : InitOpts.RemappedFiles) {
263*0a6a1f1dSLionel Sambuc // Find the file that we're mapping to.
264*0a6a1f1dSLionel Sambuc const FileEntry *ToFile = FileMgr.getFile(RF.second);
265*0a6a1f1dSLionel Sambuc if (!ToFile) {
266*0a6a1f1dSLionel Sambuc Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
267*0a6a1f1dSLionel Sambuc continue;
268*0a6a1f1dSLionel Sambuc }
269*0a6a1f1dSLionel Sambuc
270*0a6a1f1dSLionel Sambuc // Create the file entry for the file that we're mapping from.
271*0a6a1f1dSLionel Sambuc const FileEntry *FromFile =
272*0a6a1f1dSLionel Sambuc FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0);
273*0a6a1f1dSLionel Sambuc if (!FromFile) {
274*0a6a1f1dSLionel Sambuc Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first;
275*0a6a1f1dSLionel Sambuc continue;
276*0a6a1f1dSLionel Sambuc }
277*0a6a1f1dSLionel Sambuc
278*0a6a1f1dSLionel Sambuc // Override the contents of the "from" file with the contents of
279*0a6a1f1dSLionel Sambuc // the "to" file.
280*0a6a1f1dSLionel Sambuc SourceMgr.overrideFileContents(FromFile, ToFile);
281*0a6a1f1dSLionel Sambuc }
282*0a6a1f1dSLionel Sambuc
283*0a6a1f1dSLionel Sambuc SourceMgr.setOverridenFilesKeepOriginalName(
284*0a6a1f1dSLionel Sambuc InitOpts.RemappedFilesKeepOriginalName);
285*0a6a1f1dSLionel Sambuc }
286*0a6a1f1dSLionel Sambuc
287f4a2713aSLionel Sambuc // Preprocessor
288f4a2713aSLionel Sambuc
createPreprocessor(TranslationUnitKind TUKind)289*0a6a1f1dSLionel Sambuc void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
290f4a2713aSLionel Sambuc const PreprocessorOptions &PPOpts = getPreprocessorOpts();
291f4a2713aSLionel Sambuc
292f4a2713aSLionel Sambuc // Create a PTH manager if we are using some form of a token cache.
293*0a6a1f1dSLionel Sambuc PTHManager *PTHMgr = nullptr;
294f4a2713aSLionel Sambuc if (!PPOpts.TokenCache.empty())
295f4a2713aSLionel Sambuc PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics());
296f4a2713aSLionel Sambuc
297f4a2713aSLionel Sambuc // Create the Preprocessor.
298f4a2713aSLionel Sambuc HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(),
299f4a2713aSLionel Sambuc getSourceManager(),
300f4a2713aSLionel Sambuc getDiagnostics(),
301f4a2713aSLionel Sambuc getLangOpts(),
302f4a2713aSLionel Sambuc &getTarget());
303*0a6a1f1dSLionel Sambuc PP = new Preprocessor(&getPreprocessorOpts(), getDiagnostics(), getLangOpts(),
304f4a2713aSLionel Sambuc getSourceManager(), *HeaderInfo, *this, PTHMgr,
305*0a6a1f1dSLionel Sambuc /*OwnsHeaderSearch=*/true, TUKind);
306*0a6a1f1dSLionel Sambuc PP->Initialize(getTarget());
307f4a2713aSLionel Sambuc
308f4a2713aSLionel Sambuc // Note that this is different then passing PTHMgr to Preprocessor's ctor.
309f4a2713aSLionel Sambuc // That argument is used as the IdentifierInfoLookup argument to
310f4a2713aSLionel Sambuc // IdentifierTable's ctor.
311f4a2713aSLionel Sambuc if (PTHMgr) {
312f4a2713aSLionel Sambuc PTHMgr->setPreprocessor(&*PP);
313f4a2713aSLionel Sambuc PP->setPTHManager(PTHMgr);
314f4a2713aSLionel Sambuc }
315f4a2713aSLionel Sambuc
316f4a2713aSLionel Sambuc if (PPOpts.DetailedRecord)
317f4a2713aSLionel Sambuc PP->createPreprocessingRecord();
318f4a2713aSLionel Sambuc
319*0a6a1f1dSLionel Sambuc // Apply remappings to the source manager.
320*0a6a1f1dSLionel Sambuc InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(),
321*0a6a1f1dSLionel Sambuc PP->getFileManager(), PPOpts);
322*0a6a1f1dSLionel Sambuc
323*0a6a1f1dSLionel Sambuc // Predefine macros and configure the preprocessor.
324*0a6a1f1dSLionel Sambuc InitializePreprocessor(*PP, PPOpts, getFrontendOpts());
325*0a6a1f1dSLionel Sambuc
326*0a6a1f1dSLionel Sambuc // Initialize the header search object.
327*0a6a1f1dSLionel Sambuc ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(),
328*0a6a1f1dSLionel Sambuc PP->getLangOpts(), PP->getTargetInfo().getTriple());
329f4a2713aSLionel Sambuc
330f4a2713aSLionel Sambuc PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP);
331f4a2713aSLionel Sambuc
332f4a2713aSLionel Sambuc // Set up the module path, including the hash for the
333f4a2713aSLionel Sambuc // module-creation options.
334f4a2713aSLionel Sambuc SmallString<256> SpecificModuleCache(
335f4a2713aSLionel Sambuc getHeaderSearchOpts().ModuleCachePath);
336f4a2713aSLionel Sambuc if (!getHeaderSearchOpts().DisableModuleHash)
337f4a2713aSLionel Sambuc llvm::sys::path::append(SpecificModuleCache,
338f4a2713aSLionel Sambuc getInvocation().getModuleHash());
339f4a2713aSLionel Sambuc PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache);
340f4a2713aSLionel Sambuc
341f4a2713aSLionel Sambuc // Handle generating dependencies, if requested.
342f4a2713aSLionel Sambuc const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
343f4a2713aSLionel Sambuc if (!DepOpts.OutputFile.empty())
344*0a6a1f1dSLionel Sambuc TheDependencyFileGenerator.reset(
345*0a6a1f1dSLionel Sambuc DependencyFileGenerator::CreateAndAttachToPreprocessor(*PP, DepOpts));
346f4a2713aSLionel Sambuc if (!DepOpts.DOTOutputFile.empty())
347f4a2713aSLionel Sambuc AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,
348f4a2713aSLionel Sambuc getHeaderSearchOpts().Sysroot);
349f4a2713aSLionel Sambuc
350*0a6a1f1dSLionel Sambuc for (auto &Listener : DependencyCollectors)
351*0a6a1f1dSLionel Sambuc Listener->attachToPreprocessor(*PP);
352*0a6a1f1dSLionel Sambuc
353*0a6a1f1dSLionel Sambuc // If we don't have a collector, but we are collecting module dependencies,
354*0a6a1f1dSLionel Sambuc // then we're the top level compiler instance and need to create one.
355*0a6a1f1dSLionel Sambuc if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty())
356*0a6a1f1dSLionel Sambuc ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
357*0a6a1f1dSLionel Sambuc DepOpts.ModuleDependencyOutputDir);
358f4a2713aSLionel Sambuc
359f4a2713aSLionel Sambuc // Handle generating header include information, if requested.
360f4a2713aSLionel Sambuc if (DepOpts.ShowHeaderIncludes)
361f4a2713aSLionel Sambuc AttachHeaderIncludeGen(*PP);
362f4a2713aSLionel Sambuc if (!DepOpts.HeaderIncludeOutputFile.empty()) {
363f4a2713aSLionel Sambuc StringRef OutputPath = DepOpts.HeaderIncludeOutputFile;
364f4a2713aSLionel Sambuc if (OutputPath == "-")
365f4a2713aSLionel Sambuc OutputPath = "";
366f4a2713aSLionel Sambuc AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath,
367f4a2713aSLionel Sambuc /*ShowDepth=*/false);
368f4a2713aSLionel Sambuc }
369f4a2713aSLionel Sambuc
370f4a2713aSLionel Sambuc if (DepOpts.PrintShowIncludes) {
371f4a2713aSLionel Sambuc AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/false, /*OutputPath=*/"",
372f4a2713aSLionel Sambuc /*ShowDepth=*/true, /*MSStyle=*/true);
373f4a2713aSLionel Sambuc }
374*0a6a1f1dSLionel Sambuc
375*0a6a1f1dSLionel Sambuc // Load all explictly-specified module map files.
376*0a6a1f1dSLionel Sambuc for (const auto &Filename : getFrontendOpts().ModuleMapFiles) {
377*0a6a1f1dSLionel Sambuc if (auto *File = getFileManager().getFile(Filename))
378*0a6a1f1dSLionel Sambuc PP->getHeaderSearchInfo().loadModuleMapFile(File, /*IsSystem*/false);
379*0a6a1f1dSLionel Sambuc else
380*0a6a1f1dSLionel Sambuc getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
381*0a6a1f1dSLionel Sambuc }
382f4a2713aSLionel Sambuc }
383f4a2713aSLionel Sambuc
384f4a2713aSLionel Sambuc // ASTContext
385f4a2713aSLionel Sambuc
createASTContext()386f4a2713aSLionel Sambuc void CompilerInstance::createASTContext() {
387f4a2713aSLionel Sambuc Preprocessor &PP = getPreprocessor();
388f4a2713aSLionel Sambuc Context = new ASTContext(getLangOpts(), PP.getSourceManager(),
389*0a6a1f1dSLionel Sambuc PP.getIdentifierTable(), PP.getSelectorTable(),
390*0a6a1f1dSLionel Sambuc PP.getBuiltinInfo());
391*0a6a1f1dSLionel Sambuc Context->InitBuiltinTypes(getTarget());
392f4a2713aSLionel Sambuc }
393f4a2713aSLionel Sambuc
394f4a2713aSLionel Sambuc // ExternalASTSource
395f4a2713aSLionel Sambuc
createPCHExternalASTSource(StringRef Path,bool DisablePCHValidation,bool AllowPCHWithCompilerErrors,void * DeserializationListener,bool OwnDeserializationListener)396*0a6a1f1dSLionel Sambuc void CompilerInstance::createPCHExternalASTSource(
397*0a6a1f1dSLionel Sambuc StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors,
398*0a6a1f1dSLionel Sambuc void *DeserializationListener, bool OwnDeserializationListener) {
399*0a6a1f1dSLionel Sambuc IntrusiveRefCntPtr<ExternalASTSource> Source;
400f4a2713aSLionel Sambuc bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
401*0a6a1f1dSLionel Sambuc Source = createPCHExternalASTSource(
402*0a6a1f1dSLionel Sambuc Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,
403*0a6a1f1dSLionel Sambuc AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(),
404*0a6a1f1dSLionel Sambuc DeserializationListener, OwnDeserializationListener, Preamble,
405*0a6a1f1dSLionel Sambuc getFrontendOpts().UseGlobalModuleIndex);
406f4a2713aSLionel Sambuc ModuleManager = static_cast<ASTReader*>(Source.get());
407f4a2713aSLionel Sambuc getASTContext().setExternalSource(Source);
408f4a2713aSLionel Sambuc }
409f4a2713aSLionel Sambuc
createPCHExternalASTSource(StringRef Path,const std::string & Sysroot,bool DisablePCHValidation,bool AllowPCHWithCompilerErrors,Preprocessor & PP,ASTContext & Context,void * DeserializationListener,bool OwnDeserializationListener,bool Preamble,bool UseGlobalModuleIndex)410*0a6a1f1dSLionel Sambuc ExternalASTSource *CompilerInstance::createPCHExternalASTSource(
411*0a6a1f1dSLionel Sambuc StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,
412*0a6a1f1dSLionel Sambuc bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
413*0a6a1f1dSLionel Sambuc void *DeserializationListener, bool OwnDeserializationListener,
414*0a6a1f1dSLionel Sambuc bool Preamble, bool UseGlobalModuleIndex) {
415*0a6a1f1dSLionel Sambuc HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
416*0a6a1f1dSLionel Sambuc
417*0a6a1f1dSLionel Sambuc std::unique_ptr<ASTReader> Reader;
418f4a2713aSLionel Sambuc Reader.reset(new ASTReader(PP, Context,
419f4a2713aSLionel Sambuc Sysroot.empty() ? "" : Sysroot.c_str(),
420f4a2713aSLionel Sambuc DisablePCHValidation,
421f4a2713aSLionel Sambuc AllowPCHWithCompilerErrors,
422*0a6a1f1dSLionel Sambuc /*AllowConfigurationMismatch*/false,
423*0a6a1f1dSLionel Sambuc HSOpts.ModulesValidateSystemHeaders,
424f4a2713aSLionel Sambuc UseGlobalModuleIndex));
425f4a2713aSLionel Sambuc
426f4a2713aSLionel Sambuc Reader->setDeserializationListener(
427*0a6a1f1dSLionel Sambuc static_cast<ASTDeserializationListener *>(DeserializationListener),
428*0a6a1f1dSLionel Sambuc /*TakeOwnership=*/OwnDeserializationListener);
429f4a2713aSLionel Sambuc switch (Reader->ReadAST(Path,
430f4a2713aSLionel Sambuc Preamble ? serialization::MK_Preamble
431f4a2713aSLionel Sambuc : serialization::MK_PCH,
432f4a2713aSLionel Sambuc SourceLocation(),
433f4a2713aSLionel Sambuc ASTReader::ARR_None)) {
434f4a2713aSLionel Sambuc case ASTReader::Success:
435f4a2713aSLionel Sambuc // Set the predefines buffer as suggested by the PCH reader. Typically, the
436f4a2713aSLionel Sambuc // predefines buffer will be empty.
437f4a2713aSLionel Sambuc PP.setPredefines(Reader->getSuggestedPredefines());
438*0a6a1f1dSLionel Sambuc return Reader.release();
439f4a2713aSLionel Sambuc
440f4a2713aSLionel Sambuc case ASTReader::Failure:
441f4a2713aSLionel Sambuc // Unrecoverable failure: don't even try to process the input file.
442f4a2713aSLionel Sambuc break;
443f4a2713aSLionel Sambuc
444f4a2713aSLionel Sambuc case ASTReader::Missing:
445f4a2713aSLionel Sambuc case ASTReader::OutOfDate:
446f4a2713aSLionel Sambuc case ASTReader::VersionMismatch:
447f4a2713aSLionel Sambuc case ASTReader::ConfigurationMismatch:
448f4a2713aSLionel Sambuc case ASTReader::HadErrors:
449f4a2713aSLionel Sambuc // No suitable PCH file could be found. Return an error.
450f4a2713aSLionel Sambuc break;
451f4a2713aSLionel Sambuc }
452f4a2713aSLionel Sambuc
453*0a6a1f1dSLionel Sambuc return nullptr;
454f4a2713aSLionel Sambuc }
455f4a2713aSLionel Sambuc
456f4a2713aSLionel Sambuc // Code Completion
457f4a2713aSLionel Sambuc
EnableCodeCompletion(Preprocessor & PP,const std::string & Filename,unsigned Line,unsigned Column)458f4a2713aSLionel Sambuc static bool EnableCodeCompletion(Preprocessor &PP,
459f4a2713aSLionel Sambuc const std::string &Filename,
460f4a2713aSLionel Sambuc unsigned Line,
461f4a2713aSLionel Sambuc unsigned Column) {
462f4a2713aSLionel Sambuc // Tell the source manager to chop off the given file at a specific
463f4a2713aSLionel Sambuc // line and column.
464f4a2713aSLionel Sambuc const FileEntry *Entry = PP.getFileManager().getFile(Filename);
465f4a2713aSLionel Sambuc if (!Entry) {
466f4a2713aSLionel Sambuc PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
467f4a2713aSLionel Sambuc << Filename;
468f4a2713aSLionel Sambuc return true;
469f4a2713aSLionel Sambuc }
470f4a2713aSLionel Sambuc
471f4a2713aSLionel Sambuc // Truncate the named file at the given line/column.
472f4a2713aSLionel Sambuc PP.SetCodeCompletionPoint(Entry, Line, Column);
473f4a2713aSLionel Sambuc return false;
474f4a2713aSLionel Sambuc }
475f4a2713aSLionel Sambuc
createCodeCompletionConsumer()476f4a2713aSLionel Sambuc void CompilerInstance::createCodeCompletionConsumer() {
477f4a2713aSLionel Sambuc const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt;
478f4a2713aSLionel Sambuc if (!CompletionConsumer) {
479f4a2713aSLionel Sambuc setCodeCompletionConsumer(
480f4a2713aSLionel Sambuc createCodeCompletionConsumer(getPreprocessor(),
481f4a2713aSLionel Sambuc Loc.FileName, Loc.Line, Loc.Column,
482f4a2713aSLionel Sambuc getFrontendOpts().CodeCompleteOpts,
483f4a2713aSLionel Sambuc llvm::outs()));
484f4a2713aSLionel Sambuc if (!CompletionConsumer)
485f4a2713aSLionel Sambuc return;
486f4a2713aSLionel Sambuc } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName,
487f4a2713aSLionel Sambuc Loc.Line, Loc.Column)) {
488*0a6a1f1dSLionel Sambuc setCodeCompletionConsumer(nullptr);
489f4a2713aSLionel Sambuc return;
490f4a2713aSLionel Sambuc }
491f4a2713aSLionel Sambuc
492f4a2713aSLionel Sambuc if (CompletionConsumer->isOutputBinary() &&
493f4a2713aSLionel Sambuc llvm::sys::ChangeStdoutToBinary()) {
494f4a2713aSLionel Sambuc getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary);
495*0a6a1f1dSLionel Sambuc setCodeCompletionConsumer(nullptr);
496f4a2713aSLionel Sambuc }
497f4a2713aSLionel Sambuc }
498f4a2713aSLionel Sambuc
createFrontendTimer()499f4a2713aSLionel Sambuc void CompilerInstance::createFrontendTimer() {
500f4a2713aSLionel Sambuc FrontendTimer.reset(new llvm::Timer("Clang front-end timer"));
501f4a2713aSLionel Sambuc }
502f4a2713aSLionel Sambuc
503f4a2713aSLionel Sambuc CodeCompleteConsumer *
createCodeCompletionConsumer(Preprocessor & PP,const std::string & Filename,unsigned Line,unsigned Column,const CodeCompleteOptions & Opts,raw_ostream & OS)504f4a2713aSLionel Sambuc CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP,
505f4a2713aSLionel Sambuc const std::string &Filename,
506f4a2713aSLionel Sambuc unsigned Line,
507f4a2713aSLionel Sambuc unsigned Column,
508f4a2713aSLionel Sambuc const CodeCompleteOptions &Opts,
509f4a2713aSLionel Sambuc raw_ostream &OS) {
510f4a2713aSLionel Sambuc if (EnableCodeCompletion(PP, Filename, Line, Column))
511*0a6a1f1dSLionel Sambuc return nullptr;
512f4a2713aSLionel Sambuc
513f4a2713aSLionel Sambuc // Set up the creation routine for code-completion.
514f4a2713aSLionel Sambuc return new PrintingCodeCompleteConsumer(Opts, OS);
515f4a2713aSLionel Sambuc }
516f4a2713aSLionel Sambuc
createSema(TranslationUnitKind TUKind,CodeCompleteConsumer * CompletionConsumer)517f4a2713aSLionel Sambuc void CompilerInstance::createSema(TranslationUnitKind TUKind,
518f4a2713aSLionel Sambuc CodeCompleteConsumer *CompletionConsumer) {
519f4a2713aSLionel Sambuc TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(),
520f4a2713aSLionel Sambuc TUKind, CompletionConsumer));
521f4a2713aSLionel Sambuc }
522f4a2713aSLionel Sambuc
523f4a2713aSLionel Sambuc // Output Files
524f4a2713aSLionel Sambuc
addOutputFile(const OutputFile & OutFile)525f4a2713aSLionel Sambuc void CompilerInstance::addOutputFile(const OutputFile &OutFile) {
526f4a2713aSLionel Sambuc assert(OutFile.OS && "Attempt to add empty stream to output list!");
527f4a2713aSLionel Sambuc OutputFiles.push_back(OutFile);
528f4a2713aSLionel Sambuc }
529f4a2713aSLionel Sambuc
clearOutputFiles(bool EraseFiles)530f4a2713aSLionel Sambuc void CompilerInstance::clearOutputFiles(bool EraseFiles) {
531f4a2713aSLionel Sambuc for (std::list<OutputFile>::iterator
532f4a2713aSLionel Sambuc it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) {
533f4a2713aSLionel Sambuc delete it->OS;
534f4a2713aSLionel Sambuc if (!it->TempFilename.empty()) {
535f4a2713aSLionel Sambuc if (EraseFiles) {
536*0a6a1f1dSLionel Sambuc llvm::sys::fs::remove(it->TempFilename);
537f4a2713aSLionel Sambuc } else {
538f4a2713aSLionel Sambuc SmallString<128> NewOutFile(it->Filename);
539f4a2713aSLionel Sambuc
540f4a2713aSLionel Sambuc // If '-working-directory' was passed, the output filename should be
541f4a2713aSLionel Sambuc // relative to that.
542f4a2713aSLionel Sambuc FileMgr->FixupRelativePath(NewOutFile);
543*0a6a1f1dSLionel Sambuc if (std::error_code ec =
544*0a6a1f1dSLionel Sambuc llvm::sys::fs::rename(it->TempFilename, NewOutFile.str())) {
545f4a2713aSLionel Sambuc getDiagnostics().Report(diag::err_unable_to_rename_temp)
546f4a2713aSLionel Sambuc << it->TempFilename << it->Filename << ec.message();
547f4a2713aSLionel Sambuc
548*0a6a1f1dSLionel Sambuc llvm::sys::fs::remove(it->TempFilename);
549f4a2713aSLionel Sambuc }
550f4a2713aSLionel Sambuc }
551f4a2713aSLionel Sambuc } else if (!it->Filename.empty() && EraseFiles)
552f4a2713aSLionel Sambuc llvm::sys::fs::remove(it->Filename);
553f4a2713aSLionel Sambuc
554f4a2713aSLionel Sambuc }
555f4a2713aSLionel Sambuc OutputFiles.clear();
556f4a2713aSLionel Sambuc }
557f4a2713aSLionel Sambuc
558f4a2713aSLionel Sambuc llvm::raw_fd_ostream *
createDefaultOutputFile(bool Binary,StringRef InFile,StringRef Extension)559f4a2713aSLionel Sambuc CompilerInstance::createDefaultOutputFile(bool Binary,
560f4a2713aSLionel Sambuc StringRef InFile,
561f4a2713aSLionel Sambuc StringRef Extension) {
562f4a2713aSLionel Sambuc return createOutputFile(getFrontendOpts().OutputFile, Binary,
563f4a2713aSLionel Sambuc /*RemoveFileOnSignal=*/true, InFile, Extension,
564f4a2713aSLionel Sambuc /*UseTemporary=*/true);
565f4a2713aSLionel Sambuc }
566f4a2713aSLionel Sambuc
createNullOutputFile()567*0a6a1f1dSLionel Sambuc llvm::raw_null_ostream *CompilerInstance::createNullOutputFile() {
568*0a6a1f1dSLionel Sambuc llvm::raw_null_ostream *OS = new llvm::raw_null_ostream();
569*0a6a1f1dSLionel Sambuc addOutputFile(OutputFile("", "", OS));
570*0a6a1f1dSLionel Sambuc return OS;
571*0a6a1f1dSLionel Sambuc }
572*0a6a1f1dSLionel Sambuc
573f4a2713aSLionel Sambuc llvm::raw_fd_ostream *
createOutputFile(StringRef OutputPath,bool Binary,bool RemoveFileOnSignal,StringRef InFile,StringRef Extension,bool UseTemporary,bool CreateMissingDirectories)574f4a2713aSLionel Sambuc CompilerInstance::createOutputFile(StringRef OutputPath,
575f4a2713aSLionel Sambuc bool Binary, bool RemoveFileOnSignal,
576f4a2713aSLionel Sambuc StringRef InFile,
577f4a2713aSLionel Sambuc StringRef Extension,
578f4a2713aSLionel Sambuc bool UseTemporary,
579f4a2713aSLionel Sambuc bool CreateMissingDirectories) {
580*0a6a1f1dSLionel Sambuc std::string OutputPathName, TempPathName;
581*0a6a1f1dSLionel Sambuc std::error_code EC;
582*0a6a1f1dSLionel Sambuc llvm::raw_fd_ostream *OS = createOutputFile(
583*0a6a1f1dSLionel Sambuc OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension,
584*0a6a1f1dSLionel Sambuc UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName);
585f4a2713aSLionel Sambuc if (!OS) {
586*0a6a1f1dSLionel Sambuc getDiagnostics().Report(diag::err_fe_unable_to_open_output) << OutputPath
587*0a6a1f1dSLionel Sambuc << EC.message();
588*0a6a1f1dSLionel Sambuc return nullptr;
589f4a2713aSLionel Sambuc }
590f4a2713aSLionel Sambuc
591f4a2713aSLionel Sambuc // Add the output file -- but don't try to remove "-", since this means we are
592f4a2713aSLionel Sambuc // using stdin.
593f4a2713aSLionel Sambuc addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "",
594f4a2713aSLionel Sambuc TempPathName, OS));
595f4a2713aSLionel Sambuc
596f4a2713aSLionel Sambuc return OS;
597f4a2713aSLionel Sambuc }
598f4a2713aSLionel Sambuc
createOutputFile(StringRef OutputPath,std::error_code & Error,bool Binary,bool RemoveFileOnSignal,StringRef InFile,StringRef Extension,bool UseTemporary,bool CreateMissingDirectories,std::string * ResultPathName,std::string * TempPathName)599*0a6a1f1dSLionel Sambuc llvm::raw_fd_ostream *CompilerInstance::createOutputFile(
600*0a6a1f1dSLionel Sambuc StringRef OutputPath, std::error_code &Error, bool Binary,
601*0a6a1f1dSLionel Sambuc bool RemoveFileOnSignal, StringRef InFile, StringRef Extension,
602*0a6a1f1dSLionel Sambuc bool UseTemporary, bool CreateMissingDirectories,
603*0a6a1f1dSLionel Sambuc std::string *ResultPathName, std::string *TempPathName) {
604f4a2713aSLionel Sambuc assert((!CreateMissingDirectories || UseTemporary) &&
605f4a2713aSLionel Sambuc "CreateMissingDirectories is only allowed when using temporary files");
606f4a2713aSLionel Sambuc
607f4a2713aSLionel Sambuc std::string OutFile, TempFile;
608f4a2713aSLionel Sambuc if (!OutputPath.empty()) {
609f4a2713aSLionel Sambuc OutFile = OutputPath;
610f4a2713aSLionel Sambuc } else if (InFile == "-") {
611f4a2713aSLionel Sambuc OutFile = "-";
612f4a2713aSLionel Sambuc } else if (!Extension.empty()) {
613f4a2713aSLionel Sambuc SmallString<128> Path(InFile);
614f4a2713aSLionel Sambuc llvm::sys::path::replace_extension(Path, Extension);
615f4a2713aSLionel Sambuc OutFile = Path.str();
616f4a2713aSLionel Sambuc } else {
617f4a2713aSLionel Sambuc OutFile = "-";
618f4a2713aSLionel Sambuc }
619f4a2713aSLionel Sambuc
620*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::raw_fd_ostream> OS;
621f4a2713aSLionel Sambuc std::string OSFile;
622f4a2713aSLionel Sambuc
623f4a2713aSLionel Sambuc if (UseTemporary) {
624f4a2713aSLionel Sambuc if (OutFile == "-")
625f4a2713aSLionel Sambuc UseTemporary = false;
626f4a2713aSLionel Sambuc else {
627f4a2713aSLionel Sambuc llvm::sys::fs::file_status Status;
628f4a2713aSLionel Sambuc llvm::sys::fs::status(OutputPath, Status);
629f4a2713aSLionel Sambuc if (llvm::sys::fs::exists(Status)) {
630f4a2713aSLionel Sambuc // Fail early if we can't write to the final destination.
631f4a2713aSLionel Sambuc if (!llvm::sys::fs::can_write(OutputPath))
632*0a6a1f1dSLionel Sambuc return nullptr;
633f4a2713aSLionel Sambuc
634f4a2713aSLionel Sambuc // Don't use a temporary if the output is a special file. This handles
635f4a2713aSLionel Sambuc // things like '-o /dev/null'
636f4a2713aSLionel Sambuc if (!llvm::sys::fs::is_regular_file(Status))
637f4a2713aSLionel Sambuc UseTemporary = false;
638f4a2713aSLionel Sambuc }
639f4a2713aSLionel Sambuc }
640f4a2713aSLionel Sambuc }
641f4a2713aSLionel Sambuc
642f4a2713aSLionel Sambuc if (UseTemporary) {
643f4a2713aSLionel Sambuc // Create a temporary file.
644f4a2713aSLionel Sambuc SmallString<128> TempPath;
645f4a2713aSLionel Sambuc TempPath = OutFile;
646f4a2713aSLionel Sambuc TempPath += "-%%%%%%%%";
647f4a2713aSLionel Sambuc int fd;
648*0a6a1f1dSLionel Sambuc std::error_code EC =
649f4a2713aSLionel Sambuc llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath);
650f4a2713aSLionel Sambuc
651f4a2713aSLionel Sambuc if (CreateMissingDirectories &&
652f4a2713aSLionel Sambuc EC == llvm::errc::no_such_file_or_directory) {
653f4a2713aSLionel Sambuc StringRef Parent = llvm::sys::path::parent_path(OutputPath);
654f4a2713aSLionel Sambuc EC = llvm::sys::fs::create_directories(Parent);
655f4a2713aSLionel Sambuc if (!EC) {
656f4a2713aSLionel Sambuc EC = llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath);
657f4a2713aSLionel Sambuc }
658f4a2713aSLionel Sambuc }
659f4a2713aSLionel Sambuc
660f4a2713aSLionel Sambuc if (!EC) {
661f4a2713aSLionel Sambuc OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true));
662f4a2713aSLionel Sambuc OSFile = TempFile = TempPath.str();
663f4a2713aSLionel Sambuc }
664f4a2713aSLionel Sambuc // If we failed to create the temporary, fallback to writing to the file
665f4a2713aSLionel Sambuc // directly. This handles the corner case where we cannot write to the
666f4a2713aSLionel Sambuc // directory, but can write to the file.
667f4a2713aSLionel Sambuc }
668f4a2713aSLionel Sambuc
669f4a2713aSLionel Sambuc if (!OS) {
670f4a2713aSLionel Sambuc OSFile = OutFile;
671f4a2713aSLionel Sambuc OS.reset(new llvm::raw_fd_ostream(
672*0a6a1f1dSLionel Sambuc OSFile, Error,
673*0a6a1f1dSLionel Sambuc (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text)));
674*0a6a1f1dSLionel Sambuc if (Error)
675*0a6a1f1dSLionel Sambuc return nullptr;
676f4a2713aSLionel Sambuc }
677f4a2713aSLionel Sambuc
678f4a2713aSLionel Sambuc // Make sure the out stream file gets removed if we crash.
679f4a2713aSLionel Sambuc if (RemoveFileOnSignal)
680f4a2713aSLionel Sambuc llvm::sys::RemoveFileOnSignal(OSFile);
681f4a2713aSLionel Sambuc
682f4a2713aSLionel Sambuc if (ResultPathName)
683f4a2713aSLionel Sambuc *ResultPathName = OutFile;
684f4a2713aSLionel Sambuc if (TempPathName)
685f4a2713aSLionel Sambuc *TempPathName = TempFile;
686f4a2713aSLionel Sambuc
687*0a6a1f1dSLionel Sambuc return OS.release();
688f4a2713aSLionel Sambuc }
689f4a2713aSLionel Sambuc
690f4a2713aSLionel Sambuc // Initialization Utilities
691f4a2713aSLionel Sambuc
InitializeSourceManager(const FrontendInputFile & Input)692f4a2713aSLionel Sambuc bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){
693f4a2713aSLionel Sambuc return InitializeSourceManager(Input, getDiagnostics(),
694f4a2713aSLionel Sambuc getFileManager(), getSourceManager(),
695f4a2713aSLionel Sambuc getFrontendOpts());
696f4a2713aSLionel Sambuc }
697f4a2713aSLionel Sambuc
InitializeSourceManager(const FrontendInputFile & Input,DiagnosticsEngine & Diags,FileManager & FileMgr,SourceManager & SourceMgr,const FrontendOptions & Opts)698f4a2713aSLionel Sambuc bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input,
699f4a2713aSLionel Sambuc DiagnosticsEngine &Diags,
700f4a2713aSLionel Sambuc FileManager &FileMgr,
701f4a2713aSLionel Sambuc SourceManager &SourceMgr,
702f4a2713aSLionel Sambuc const FrontendOptions &Opts) {
703f4a2713aSLionel Sambuc SrcMgr::CharacteristicKind
704f4a2713aSLionel Sambuc Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
705f4a2713aSLionel Sambuc
706f4a2713aSLionel Sambuc if (Input.isBuffer()) {
707*0a6a1f1dSLionel Sambuc SourceMgr.setMainFileID(SourceMgr.createFileID(
708*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::MemoryBuffer>(Input.getBuffer()), Kind));
709f4a2713aSLionel Sambuc assert(!SourceMgr.getMainFileID().isInvalid() &&
710f4a2713aSLionel Sambuc "Couldn't establish MainFileID!");
711f4a2713aSLionel Sambuc return true;
712f4a2713aSLionel Sambuc }
713f4a2713aSLionel Sambuc
714f4a2713aSLionel Sambuc StringRef InputFile = Input.getFile();
715f4a2713aSLionel Sambuc
716f4a2713aSLionel Sambuc // Figure out where to get and map in the main file.
717f4a2713aSLionel Sambuc if (InputFile != "-") {
718f4a2713aSLionel Sambuc const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true);
719f4a2713aSLionel Sambuc if (!File) {
720f4a2713aSLionel Sambuc Diags.Report(diag::err_fe_error_reading) << InputFile;
721f4a2713aSLionel Sambuc return false;
722f4a2713aSLionel Sambuc }
723f4a2713aSLionel Sambuc
724f4a2713aSLionel Sambuc // The natural SourceManager infrastructure can't currently handle named
725f4a2713aSLionel Sambuc // pipes, but we would at least like to accept them for the main
726f4a2713aSLionel Sambuc // file. Detect them here, read them with the volatile flag so FileMgr will
727f4a2713aSLionel Sambuc // pick up the correct size, and simply override their contents as we do for
728f4a2713aSLionel Sambuc // STDIN.
729f4a2713aSLionel Sambuc if (File->isNamedPipe()) {
730*0a6a1f1dSLionel Sambuc auto MB = FileMgr.getBufferForFile(File, /*isVolatile=*/true);
731*0a6a1f1dSLionel Sambuc if (MB) {
732f4a2713aSLionel Sambuc // Create a new virtual file that will have the correct size.
733*0a6a1f1dSLionel Sambuc File = FileMgr.getVirtualFile(InputFile, (*MB)->getBufferSize(), 0);
734*0a6a1f1dSLionel Sambuc SourceMgr.overrideFileContents(File, std::move(*MB));
735f4a2713aSLionel Sambuc } else {
736*0a6a1f1dSLionel Sambuc Diags.Report(diag::err_cannot_open_file) << InputFile
737*0a6a1f1dSLionel Sambuc << MB.getError().message();
738f4a2713aSLionel Sambuc return false;
739f4a2713aSLionel Sambuc }
740f4a2713aSLionel Sambuc }
741f4a2713aSLionel Sambuc
742*0a6a1f1dSLionel Sambuc SourceMgr.setMainFileID(
743*0a6a1f1dSLionel Sambuc SourceMgr.createFileID(File, SourceLocation(), Kind));
744f4a2713aSLionel Sambuc } else {
745*0a6a1f1dSLionel Sambuc llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> SBOrErr =
746*0a6a1f1dSLionel Sambuc llvm::MemoryBuffer::getSTDIN();
747*0a6a1f1dSLionel Sambuc if (std::error_code EC = SBOrErr.getError()) {
748*0a6a1f1dSLionel Sambuc Diags.Report(diag::err_fe_error_reading_stdin) << EC.message();
749f4a2713aSLionel Sambuc return false;
750f4a2713aSLionel Sambuc }
751*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::MemoryBuffer> SB = std::move(SBOrErr.get());
752*0a6a1f1dSLionel Sambuc
753f4a2713aSLionel Sambuc const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(),
754f4a2713aSLionel Sambuc SB->getBufferSize(), 0);
755*0a6a1f1dSLionel Sambuc SourceMgr.setMainFileID(
756*0a6a1f1dSLionel Sambuc SourceMgr.createFileID(File, SourceLocation(), Kind));
757*0a6a1f1dSLionel Sambuc SourceMgr.overrideFileContents(File, std::move(SB));
758f4a2713aSLionel Sambuc }
759f4a2713aSLionel Sambuc
760f4a2713aSLionel Sambuc assert(!SourceMgr.getMainFileID().isInvalid() &&
761f4a2713aSLionel Sambuc "Couldn't establish MainFileID!");
762f4a2713aSLionel Sambuc return true;
763f4a2713aSLionel Sambuc }
764f4a2713aSLionel Sambuc
765f4a2713aSLionel Sambuc // High-Level Operations
766f4a2713aSLionel Sambuc
ExecuteAction(FrontendAction & Act)767f4a2713aSLionel Sambuc bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
768f4a2713aSLionel Sambuc assert(hasDiagnostics() && "Diagnostics engine is not initialized!");
769f4a2713aSLionel Sambuc assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!");
770f4a2713aSLionel Sambuc assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!");
771f4a2713aSLionel Sambuc
772f4a2713aSLionel Sambuc // FIXME: Take this as an argument, once all the APIs we used have moved to
773f4a2713aSLionel Sambuc // taking it as an input instead of hard-coding llvm::errs.
774f4a2713aSLionel Sambuc raw_ostream &OS = llvm::errs();
775f4a2713aSLionel Sambuc
776f4a2713aSLionel Sambuc // Create the target instance.
777*0a6a1f1dSLionel Sambuc setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(),
778*0a6a1f1dSLionel Sambuc getInvocation().TargetOpts));
779f4a2713aSLionel Sambuc if (!hasTarget())
780f4a2713aSLionel Sambuc return false;
781f4a2713aSLionel Sambuc
782f4a2713aSLionel Sambuc // Inform the target of the language options.
783f4a2713aSLionel Sambuc //
784f4a2713aSLionel Sambuc // FIXME: We shouldn't need to do this, the target should be immutable once
785f4a2713aSLionel Sambuc // created. This complexity should be lifted elsewhere.
786*0a6a1f1dSLionel Sambuc getTarget().adjust(getLangOpts());
787f4a2713aSLionel Sambuc
788f4a2713aSLionel Sambuc // rewriter project will change target built-in bool type from its default.
789f4a2713aSLionel Sambuc if (getFrontendOpts().ProgramAction == frontend::RewriteObjC)
790f4a2713aSLionel Sambuc getTarget().noSignedCharForObjCBool();
791f4a2713aSLionel Sambuc
792f4a2713aSLionel Sambuc // Validate/process some options.
793f4a2713aSLionel Sambuc if (getHeaderSearchOpts().Verbose)
794f4a2713aSLionel Sambuc OS << "clang -cc1 version " CLANG_VERSION_STRING
795*0a6a1f1dSLionel Sambuc << " based upon " << BACKEND_PACKAGE_STRING
796f4a2713aSLionel Sambuc << " default target " << llvm::sys::getDefaultTargetTriple() << "\n";
797f4a2713aSLionel Sambuc
798f4a2713aSLionel Sambuc if (getFrontendOpts().ShowTimers)
799f4a2713aSLionel Sambuc createFrontendTimer();
800f4a2713aSLionel Sambuc
801f4a2713aSLionel Sambuc if (getFrontendOpts().ShowStats)
802f4a2713aSLionel Sambuc llvm::EnableStatistics();
803f4a2713aSLionel Sambuc
804f4a2713aSLionel Sambuc for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) {
805*0a6a1f1dSLionel Sambuc // Reset the ID tables if we are reusing the SourceManager and parsing
806*0a6a1f1dSLionel Sambuc // regular files.
807*0a6a1f1dSLionel Sambuc if (hasSourceManager() && !Act.isModelParsingAction())
808f4a2713aSLionel Sambuc getSourceManager().clearIDTables();
809f4a2713aSLionel Sambuc
810f4a2713aSLionel Sambuc if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) {
811f4a2713aSLionel Sambuc Act.Execute();
812f4a2713aSLionel Sambuc Act.EndSourceFile();
813f4a2713aSLionel Sambuc }
814f4a2713aSLionel Sambuc }
815f4a2713aSLionel Sambuc
816f4a2713aSLionel Sambuc // Notify the diagnostic client that all files were processed.
817f4a2713aSLionel Sambuc getDiagnostics().getClient()->finish();
818f4a2713aSLionel Sambuc
819f4a2713aSLionel Sambuc if (getDiagnosticOpts().ShowCarets) {
820f4a2713aSLionel Sambuc // We can have multiple diagnostics sharing one diagnostic client.
821f4a2713aSLionel Sambuc // Get the total number of warnings/errors from the client.
822f4a2713aSLionel Sambuc unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings();
823f4a2713aSLionel Sambuc unsigned NumErrors = getDiagnostics().getClient()->getNumErrors();
824f4a2713aSLionel Sambuc
825f4a2713aSLionel Sambuc if (NumWarnings)
826f4a2713aSLionel Sambuc OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s");
827f4a2713aSLionel Sambuc if (NumWarnings && NumErrors)
828f4a2713aSLionel Sambuc OS << " and ";
829f4a2713aSLionel Sambuc if (NumErrors)
830f4a2713aSLionel Sambuc OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s");
831f4a2713aSLionel Sambuc if (NumWarnings || NumErrors)
832f4a2713aSLionel Sambuc OS << " generated.\n";
833f4a2713aSLionel Sambuc }
834f4a2713aSLionel Sambuc
835f4a2713aSLionel Sambuc if (getFrontendOpts().ShowStats && hasFileManager()) {
836f4a2713aSLionel Sambuc getFileManager().PrintStats();
837f4a2713aSLionel Sambuc OS << "\n";
838f4a2713aSLionel Sambuc }
839f4a2713aSLionel Sambuc
840f4a2713aSLionel Sambuc return !getDiagnostics().getClient()->getNumErrors();
841f4a2713aSLionel Sambuc }
842f4a2713aSLionel Sambuc
843f4a2713aSLionel Sambuc /// \brief Determine the appropriate source input kind based on language
844f4a2713aSLionel Sambuc /// options.
getSourceInputKindFromOptions(const LangOptions & LangOpts)845f4a2713aSLionel Sambuc static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) {
846f4a2713aSLionel Sambuc if (LangOpts.OpenCL)
847f4a2713aSLionel Sambuc return IK_OpenCL;
848f4a2713aSLionel Sambuc if (LangOpts.CUDA)
849f4a2713aSLionel Sambuc return IK_CUDA;
850f4a2713aSLionel Sambuc if (LangOpts.ObjC1)
851f4a2713aSLionel Sambuc return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC;
852f4a2713aSLionel Sambuc return LangOpts.CPlusPlus? IK_CXX : IK_C;
853f4a2713aSLionel Sambuc }
854f4a2713aSLionel Sambuc
855f4a2713aSLionel Sambuc /// \brief Compile a module file for the given module, using the options
856*0a6a1f1dSLionel Sambuc /// provided by the importing compiler instance. Returns true if the module
857*0a6a1f1dSLionel Sambuc /// was built without errors.
compileModuleImpl(CompilerInstance & ImportingInstance,SourceLocation ImportLoc,Module * Module,StringRef ModuleFileName)858*0a6a1f1dSLionel Sambuc static bool compileModuleImpl(CompilerInstance &ImportingInstance,
859f4a2713aSLionel Sambuc SourceLocation ImportLoc,
860f4a2713aSLionel Sambuc Module *Module,
861f4a2713aSLionel Sambuc StringRef ModuleFileName) {
862f4a2713aSLionel Sambuc ModuleMap &ModMap
863f4a2713aSLionel Sambuc = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
864f4a2713aSLionel Sambuc
865f4a2713aSLionel Sambuc // Construct a compiler invocation for creating this module.
866f4a2713aSLionel Sambuc IntrusiveRefCntPtr<CompilerInvocation> Invocation
867f4a2713aSLionel Sambuc (new CompilerInvocation(ImportingInstance.getInvocation()));
868f4a2713aSLionel Sambuc
869f4a2713aSLionel Sambuc PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
870f4a2713aSLionel Sambuc
871f4a2713aSLionel Sambuc // For any options that aren't intended to affect how a module is built,
872f4a2713aSLionel Sambuc // reset them to their default values.
873f4a2713aSLionel Sambuc Invocation->getLangOpts()->resetNonModularOptions();
874f4a2713aSLionel Sambuc PPOpts.resetNonModularOptions();
875f4a2713aSLionel Sambuc
876f4a2713aSLionel Sambuc // Remove any macro definitions that are explicitly ignored by the module.
877f4a2713aSLionel Sambuc // They aren't supposed to affect how the module is built anyway.
878f4a2713aSLionel Sambuc const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
879*0a6a1f1dSLionel Sambuc PPOpts.Macros.erase(
880*0a6a1f1dSLionel Sambuc std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(),
881*0a6a1f1dSLionel Sambuc [&HSOpts](const std::pair<std::string, bool> &def) {
882*0a6a1f1dSLionel Sambuc StringRef MacroDef = def.first;
883*0a6a1f1dSLionel Sambuc return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0;
884*0a6a1f1dSLionel Sambuc }),
885f4a2713aSLionel Sambuc PPOpts.Macros.end());
886f4a2713aSLionel Sambuc
887f4a2713aSLionel Sambuc // Note the name of the module we're building.
888f4a2713aSLionel Sambuc Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName();
889f4a2713aSLionel Sambuc
890f4a2713aSLionel Sambuc // Make sure that the failed-module structure has been allocated in
891f4a2713aSLionel Sambuc // the importing instance, and propagate the pointer to the newly-created
892f4a2713aSLionel Sambuc // instance.
893f4a2713aSLionel Sambuc PreprocessorOptions &ImportingPPOpts
894f4a2713aSLionel Sambuc = ImportingInstance.getInvocation().getPreprocessorOpts();
895f4a2713aSLionel Sambuc if (!ImportingPPOpts.FailedModules)
896f4a2713aSLionel Sambuc ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet;
897f4a2713aSLionel Sambuc PPOpts.FailedModules = ImportingPPOpts.FailedModules;
898f4a2713aSLionel Sambuc
899f4a2713aSLionel Sambuc // If there is a module map file, build the module using the module map.
900f4a2713aSLionel Sambuc // Set up the inputs/outputs so that we build the module from its umbrella
901f4a2713aSLionel Sambuc // header.
902f4a2713aSLionel Sambuc FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
903f4a2713aSLionel Sambuc FrontendOpts.OutputFile = ModuleFileName.str();
904f4a2713aSLionel Sambuc FrontendOpts.DisableFree = false;
905f4a2713aSLionel Sambuc FrontendOpts.GenerateGlobalModuleIndex = false;
906f4a2713aSLionel Sambuc FrontendOpts.Inputs.clear();
907f4a2713aSLionel Sambuc InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts());
908f4a2713aSLionel Sambuc
909f4a2713aSLionel Sambuc // Don't free the remapped file buffers; they are owned by our caller.
910f4a2713aSLionel Sambuc PPOpts.RetainRemappedFileBuffers = true;
911f4a2713aSLionel Sambuc
912f4a2713aSLionel Sambuc Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
913f4a2713aSLionel Sambuc assert(ImportingInstance.getInvocation().getModuleHash() ==
914f4a2713aSLionel Sambuc Invocation->getModuleHash() && "Module hash mismatch!");
915f4a2713aSLionel Sambuc
916f4a2713aSLionel Sambuc // Construct a compiler instance that will be used to actually create the
917f4a2713aSLionel Sambuc // module.
918*0a6a1f1dSLionel Sambuc CompilerInstance Instance(/*BuildingModule=*/true);
919f4a2713aSLionel Sambuc Instance.setInvocation(&*Invocation);
920f4a2713aSLionel Sambuc
921f4a2713aSLionel Sambuc Instance.createDiagnostics(new ForwardingDiagnosticConsumer(
922f4a2713aSLionel Sambuc ImportingInstance.getDiagnosticClient()),
923f4a2713aSLionel Sambuc /*ShouldOwnClient=*/true);
924f4a2713aSLionel Sambuc
925*0a6a1f1dSLionel Sambuc Instance.setVirtualFileSystem(&ImportingInstance.getVirtualFileSystem());
926*0a6a1f1dSLionel Sambuc
927f4a2713aSLionel Sambuc // Note that this module is part of the module build stack, so that we
928f4a2713aSLionel Sambuc // can detect cycles in the module graph.
929*0a6a1f1dSLionel Sambuc Instance.setFileManager(&ImportingInstance.getFileManager());
930f4a2713aSLionel Sambuc Instance.createSourceManager(Instance.getFileManager());
931f4a2713aSLionel Sambuc SourceManager &SourceMgr = Instance.getSourceManager();
932f4a2713aSLionel Sambuc SourceMgr.setModuleBuildStack(
933f4a2713aSLionel Sambuc ImportingInstance.getSourceManager().getModuleBuildStack());
934f4a2713aSLionel Sambuc SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(),
935f4a2713aSLionel Sambuc FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));
936f4a2713aSLionel Sambuc
937*0a6a1f1dSLionel Sambuc // If we're collecting module dependencies, we need to share a collector
938*0a6a1f1dSLionel Sambuc // between all of the module CompilerInstances.
939*0a6a1f1dSLionel Sambuc Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector());
940*0a6a1f1dSLionel Sambuc
941f4a2713aSLionel Sambuc // Get or create the module map that we'll use to build this module.
942f4a2713aSLionel Sambuc std::string InferredModuleMapContent;
943f4a2713aSLionel Sambuc if (const FileEntry *ModuleMapFile =
944f4a2713aSLionel Sambuc ModMap.getContainingModuleMapFile(Module)) {
945f4a2713aSLionel Sambuc // Use the module map where this module resides.
946f4a2713aSLionel Sambuc FrontendOpts.Inputs.push_back(
947f4a2713aSLionel Sambuc FrontendInputFile(ModuleMapFile->getName(), IK));
948f4a2713aSLionel Sambuc } else {
949f4a2713aSLionel Sambuc llvm::raw_string_ostream OS(InferredModuleMapContent);
950f4a2713aSLionel Sambuc Module->print(OS);
951f4a2713aSLionel Sambuc OS.flush();
952f4a2713aSLionel Sambuc FrontendOpts.Inputs.push_back(
953f4a2713aSLionel Sambuc FrontendInputFile("__inferred_module.map", IK));
954f4a2713aSLionel Sambuc
955*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
956f4a2713aSLionel Sambuc llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
957f4a2713aSLionel Sambuc ModuleMapFile = Instance.getFileManager().getVirtualFile(
958f4a2713aSLionel Sambuc "__inferred_module.map", InferredModuleMapContent.size(), 0);
959*0a6a1f1dSLionel Sambuc SourceMgr.overrideFileContents(ModuleMapFile, std::move(ModuleMapBuffer));
960f4a2713aSLionel Sambuc }
961f4a2713aSLionel Sambuc
962*0a6a1f1dSLionel Sambuc // Construct a module-generating action. Passing through the module map is
963*0a6a1f1dSLionel Sambuc // safe because the FileManager is shared between the compiler instances.
964*0a6a1f1dSLionel Sambuc GenerateModuleAction CreateModuleAction(
965*0a6a1f1dSLionel Sambuc ModMap.getModuleMapFileForUniquing(Module), Module->IsSystem);
966*0a6a1f1dSLionel Sambuc
967*0a6a1f1dSLionel Sambuc ImportingInstance.getDiagnostics().Report(ImportLoc,
968*0a6a1f1dSLionel Sambuc diag::remark_module_build)
969*0a6a1f1dSLionel Sambuc << Module->Name << ModuleFileName;
970f4a2713aSLionel Sambuc
971f4a2713aSLionel Sambuc // Execute the action to actually build the module in-place. Use a separate
972f4a2713aSLionel Sambuc // thread so that we get a stack large enough.
973f4a2713aSLionel Sambuc const unsigned ThreadStackSize = 8 << 20;
974f4a2713aSLionel Sambuc llvm::CrashRecoveryContext CRC;
975*0a6a1f1dSLionel Sambuc CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(CreateModuleAction); },
976*0a6a1f1dSLionel Sambuc ThreadStackSize);
977f4a2713aSLionel Sambuc
978*0a6a1f1dSLionel Sambuc ImportingInstance.getDiagnostics().Report(ImportLoc,
979*0a6a1f1dSLionel Sambuc diag::remark_module_build_done)
980*0a6a1f1dSLionel Sambuc << Module->Name;
981f4a2713aSLionel Sambuc
982f4a2713aSLionel Sambuc // Delete the temporary module map file.
983f4a2713aSLionel Sambuc // FIXME: Even though we're executing under crash protection, it would still
984f4a2713aSLionel Sambuc // be nice to do this with RemoveFileOnSignal when we can. However, that
985f4a2713aSLionel Sambuc // doesn't make sense for all clients, so clean this up manually.
986f4a2713aSLionel Sambuc Instance.clearOutputFiles(/*EraseFiles=*/true);
987f4a2713aSLionel Sambuc
988f4a2713aSLionel Sambuc // We've rebuilt a module. If we're allowed to generate or update the global
989f4a2713aSLionel Sambuc // module index, record that fact in the importing compiler instance.
990f4a2713aSLionel Sambuc if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) {
991f4a2713aSLionel Sambuc ImportingInstance.setBuildGlobalModuleIndex(true);
992f4a2713aSLionel Sambuc }
993*0a6a1f1dSLionel Sambuc
994*0a6a1f1dSLionel Sambuc return !Instance.getDiagnostics().hasErrorOccurred();
995*0a6a1f1dSLionel Sambuc }
996*0a6a1f1dSLionel Sambuc
compileAndLoadModule(CompilerInstance & ImportingInstance,SourceLocation ImportLoc,SourceLocation ModuleNameLoc,Module * Module,StringRef ModuleFileName)997*0a6a1f1dSLionel Sambuc static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
998*0a6a1f1dSLionel Sambuc SourceLocation ImportLoc,
999*0a6a1f1dSLionel Sambuc SourceLocation ModuleNameLoc, Module *Module,
1000*0a6a1f1dSLionel Sambuc StringRef ModuleFileName) {
1001*0a6a1f1dSLionel Sambuc DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics();
1002*0a6a1f1dSLionel Sambuc
1003*0a6a1f1dSLionel Sambuc auto diagnoseBuildFailure = [&] {
1004*0a6a1f1dSLionel Sambuc Diags.Report(ModuleNameLoc, diag::err_module_not_built)
1005*0a6a1f1dSLionel Sambuc << Module->Name << SourceRange(ImportLoc, ModuleNameLoc);
1006*0a6a1f1dSLionel Sambuc };
1007*0a6a1f1dSLionel Sambuc
1008*0a6a1f1dSLionel Sambuc // FIXME: have LockFileManager return an error_code so that we can
1009*0a6a1f1dSLionel Sambuc // avoid the mkdir when the directory already exists.
1010*0a6a1f1dSLionel Sambuc StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
1011*0a6a1f1dSLionel Sambuc llvm::sys::fs::create_directories(Dir);
1012*0a6a1f1dSLionel Sambuc
1013*0a6a1f1dSLionel Sambuc while (1) {
1014*0a6a1f1dSLionel Sambuc unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing;
1015*0a6a1f1dSLionel Sambuc llvm::LockFileManager Locked(ModuleFileName);
1016*0a6a1f1dSLionel Sambuc switch (Locked) {
1017*0a6a1f1dSLionel Sambuc case llvm::LockFileManager::LFS_Error:
1018*0a6a1f1dSLionel Sambuc Diags.Report(ModuleNameLoc, diag::err_module_lock_failure)
1019*0a6a1f1dSLionel Sambuc << Module->Name;
1020*0a6a1f1dSLionel Sambuc return false;
1021*0a6a1f1dSLionel Sambuc
1022*0a6a1f1dSLionel Sambuc case llvm::LockFileManager::LFS_Owned:
1023*0a6a1f1dSLionel Sambuc // We're responsible for building the module ourselves.
1024*0a6a1f1dSLionel Sambuc if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module,
1025*0a6a1f1dSLionel Sambuc ModuleFileName)) {
1026*0a6a1f1dSLionel Sambuc diagnoseBuildFailure();
1027*0a6a1f1dSLionel Sambuc return false;
1028*0a6a1f1dSLionel Sambuc }
1029*0a6a1f1dSLionel Sambuc break;
1030*0a6a1f1dSLionel Sambuc
1031*0a6a1f1dSLionel Sambuc case llvm::LockFileManager::LFS_Shared:
1032*0a6a1f1dSLionel Sambuc // Someone else is responsible for building the module. Wait for them to
1033*0a6a1f1dSLionel Sambuc // finish.
1034*0a6a1f1dSLionel Sambuc if (Locked.waitForUnlock() == llvm::LockFileManager::Res_OwnerDied)
1035*0a6a1f1dSLionel Sambuc continue; // try again to get the lock.
1036*0a6a1f1dSLionel Sambuc ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate;
1037*0a6a1f1dSLionel Sambuc break;
1038*0a6a1f1dSLionel Sambuc }
1039*0a6a1f1dSLionel Sambuc
1040*0a6a1f1dSLionel Sambuc // Try to read the module file, now that we've compiled it.
1041*0a6a1f1dSLionel Sambuc ASTReader::ASTReadResult ReadResult =
1042*0a6a1f1dSLionel Sambuc ImportingInstance.getModuleManager()->ReadAST(
1043*0a6a1f1dSLionel Sambuc ModuleFileName, serialization::MK_ImplicitModule, ImportLoc,
1044*0a6a1f1dSLionel Sambuc ModuleLoadCapabilities);
1045*0a6a1f1dSLionel Sambuc
1046*0a6a1f1dSLionel Sambuc if (ReadResult == ASTReader::OutOfDate &&
1047*0a6a1f1dSLionel Sambuc Locked == llvm::LockFileManager::LFS_Shared) {
1048*0a6a1f1dSLionel Sambuc // The module may be out of date in the presence of file system races,
1049*0a6a1f1dSLionel Sambuc // or if one of its imports depends on header search paths that are not
1050*0a6a1f1dSLionel Sambuc // consistent with this ImportingInstance. Try again...
1051*0a6a1f1dSLionel Sambuc continue;
1052*0a6a1f1dSLionel Sambuc } else if (ReadResult == ASTReader::Missing) {
1053*0a6a1f1dSLionel Sambuc diagnoseBuildFailure();
1054*0a6a1f1dSLionel Sambuc } else if (ReadResult != ASTReader::Success &&
1055*0a6a1f1dSLionel Sambuc !Diags.hasErrorOccurred()) {
1056*0a6a1f1dSLionel Sambuc // The ASTReader didn't diagnose the error, so conservatively report it.
1057*0a6a1f1dSLionel Sambuc diagnoseBuildFailure();
1058*0a6a1f1dSLionel Sambuc }
1059*0a6a1f1dSLionel Sambuc return ReadResult == ASTReader::Success;
1060*0a6a1f1dSLionel Sambuc }
1061f4a2713aSLionel Sambuc }
1062f4a2713aSLionel Sambuc
1063f4a2713aSLionel Sambuc /// \brief Diagnose differences between the current definition of the given
1064f4a2713aSLionel Sambuc /// configuration macro and the definition provided on the command line.
checkConfigMacro(Preprocessor & PP,StringRef ConfigMacro,Module * Mod,SourceLocation ImportLoc)1065f4a2713aSLionel Sambuc static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,
1066f4a2713aSLionel Sambuc Module *Mod, SourceLocation ImportLoc) {
1067f4a2713aSLionel Sambuc IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro);
1068f4a2713aSLionel Sambuc SourceManager &SourceMgr = PP.getSourceManager();
1069f4a2713aSLionel Sambuc
1070f4a2713aSLionel Sambuc // If this identifier has never had a macro definition, then it could
1071f4a2713aSLionel Sambuc // not have changed.
1072f4a2713aSLionel Sambuc if (!Id->hadMacroDefinition())
1073f4a2713aSLionel Sambuc return;
1074f4a2713aSLionel Sambuc
1075f4a2713aSLionel Sambuc // If this identifier does not currently have a macro definition,
1076f4a2713aSLionel Sambuc // check whether it had one on the command line.
1077f4a2713aSLionel Sambuc if (!Id->hasMacroDefinition()) {
1078f4a2713aSLionel Sambuc MacroDirective::DefInfo LatestDef =
1079f4a2713aSLionel Sambuc PP.getMacroDirectiveHistory(Id)->getDefinition();
1080f4a2713aSLionel Sambuc for (MacroDirective::DefInfo Def = LatestDef; Def;
1081f4a2713aSLionel Sambuc Def = Def.getPreviousDefinition()) {
1082f4a2713aSLionel Sambuc FileID FID = SourceMgr.getFileID(Def.getLocation());
1083f4a2713aSLionel Sambuc if (FID.isInvalid())
1084f4a2713aSLionel Sambuc continue;
1085f4a2713aSLionel Sambuc
1086f4a2713aSLionel Sambuc // We only care about the predefines buffer.
1087f4a2713aSLionel Sambuc if (FID != PP.getPredefinesFileID())
1088f4a2713aSLionel Sambuc continue;
1089f4a2713aSLionel Sambuc
1090f4a2713aSLionel Sambuc // This macro was defined on the command line, then #undef'd later.
1091f4a2713aSLionel Sambuc // Complain.
1092f4a2713aSLionel Sambuc PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
1093f4a2713aSLionel Sambuc << true << ConfigMacro << Mod->getFullModuleName();
1094f4a2713aSLionel Sambuc if (LatestDef.isUndefined())
1095f4a2713aSLionel Sambuc PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
1096f4a2713aSLionel Sambuc << true;
1097f4a2713aSLionel Sambuc return;
1098f4a2713aSLionel Sambuc }
1099f4a2713aSLionel Sambuc
1100f4a2713aSLionel Sambuc // Okay: no definition in the predefines buffer.
1101f4a2713aSLionel Sambuc return;
1102f4a2713aSLionel Sambuc }
1103f4a2713aSLionel Sambuc
1104f4a2713aSLionel Sambuc // This identifier has a macro definition. Check whether we had a definition
1105f4a2713aSLionel Sambuc // on the command line.
1106f4a2713aSLionel Sambuc MacroDirective::DefInfo LatestDef =
1107f4a2713aSLionel Sambuc PP.getMacroDirectiveHistory(Id)->getDefinition();
1108f4a2713aSLionel Sambuc MacroDirective::DefInfo PredefinedDef;
1109f4a2713aSLionel Sambuc for (MacroDirective::DefInfo Def = LatestDef; Def;
1110f4a2713aSLionel Sambuc Def = Def.getPreviousDefinition()) {
1111f4a2713aSLionel Sambuc FileID FID = SourceMgr.getFileID(Def.getLocation());
1112f4a2713aSLionel Sambuc if (FID.isInvalid())
1113f4a2713aSLionel Sambuc continue;
1114f4a2713aSLionel Sambuc
1115f4a2713aSLionel Sambuc // We only care about the predefines buffer.
1116f4a2713aSLionel Sambuc if (FID != PP.getPredefinesFileID())
1117f4a2713aSLionel Sambuc continue;
1118f4a2713aSLionel Sambuc
1119f4a2713aSLionel Sambuc PredefinedDef = Def;
1120f4a2713aSLionel Sambuc break;
1121f4a2713aSLionel Sambuc }
1122f4a2713aSLionel Sambuc
1123f4a2713aSLionel Sambuc // If there was no definition for this macro in the predefines buffer,
1124f4a2713aSLionel Sambuc // complain.
1125f4a2713aSLionel Sambuc if (!PredefinedDef ||
1126f4a2713aSLionel Sambuc (!PredefinedDef.getLocation().isValid() &&
1127f4a2713aSLionel Sambuc PredefinedDef.getUndefLocation().isValid())) {
1128f4a2713aSLionel Sambuc PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
1129f4a2713aSLionel Sambuc << false << ConfigMacro << Mod->getFullModuleName();
1130f4a2713aSLionel Sambuc PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
1131f4a2713aSLionel Sambuc << false;
1132f4a2713aSLionel Sambuc return;
1133f4a2713aSLionel Sambuc }
1134f4a2713aSLionel Sambuc
1135f4a2713aSLionel Sambuc // If the current macro definition is the same as the predefined macro
1136f4a2713aSLionel Sambuc // definition, it's okay.
1137f4a2713aSLionel Sambuc if (LatestDef.getMacroInfo() == PredefinedDef.getMacroInfo() ||
1138f4a2713aSLionel Sambuc LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP,
1139f4a2713aSLionel Sambuc /*Syntactically=*/true))
1140f4a2713aSLionel Sambuc return;
1141f4a2713aSLionel Sambuc
1142f4a2713aSLionel Sambuc // The macro definitions differ.
1143f4a2713aSLionel Sambuc PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
1144f4a2713aSLionel Sambuc << false << ConfigMacro << Mod->getFullModuleName();
1145f4a2713aSLionel Sambuc PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
1146f4a2713aSLionel Sambuc << false;
1147f4a2713aSLionel Sambuc }
1148f4a2713aSLionel Sambuc
1149f4a2713aSLionel Sambuc /// \brief Write a new timestamp file with the given path.
writeTimestampFile(StringRef TimestampFile)1150f4a2713aSLionel Sambuc static void writeTimestampFile(StringRef TimestampFile) {
1151*0a6a1f1dSLionel Sambuc std::error_code EC;
1152*0a6a1f1dSLionel Sambuc llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None);
1153f4a2713aSLionel Sambuc }
1154f4a2713aSLionel Sambuc
1155f4a2713aSLionel Sambuc /// \brief Prune the module cache of modules that haven't been accessed in
1156f4a2713aSLionel Sambuc /// a long time.
pruneModuleCache(const HeaderSearchOptions & HSOpts)1157f4a2713aSLionel Sambuc static void pruneModuleCache(const HeaderSearchOptions &HSOpts) {
1158f4a2713aSLionel Sambuc struct stat StatBuf;
1159f4a2713aSLionel Sambuc llvm::SmallString<128> TimestampFile;
1160f4a2713aSLionel Sambuc TimestampFile = HSOpts.ModuleCachePath;
1161f4a2713aSLionel Sambuc llvm::sys::path::append(TimestampFile, "modules.timestamp");
1162f4a2713aSLionel Sambuc
1163f4a2713aSLionel Sambuc // Try to stat() the timestamp file.
1164f4a2713aSLionel Sambuc if (::stat(TimestampFile.c_str(), &StatBuf)) {
1165f4a2713aSLionel Sambuc // If the timestamp file wasn't there, create one now.
1166f4a2713aSLionel Sambuc if (errno == ENOENT) {
1167f4a2713aSLionel Sambuc writeTimestampFile(TimestampFile);
1168f4a2713aSLionel Sambuc }
1169f4a2713aSLionel Sambuc return;
1170f4a2713aSLionel Sambuc }
1171f4a2713aSLionel Sambuc
1172f4a2713aSLionel Sambuc // Check whether the time stamp is older than our pruning interval.
1173f4a2713aSLionel Sambuc // If not, do nothing.
1174f4a2713aSLionel Sambuc time_t TimeStampModTime = StatBuf.st_mtime;
1175*0a6a1f1dSLionel Sambuc time_t CurrentTime = time(nullptr);
1176f4a2713aSLionel Sambuc if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval))
1177f4a2713aSLionel Sambuc return;
1178f4a2713aSLionel Sambuc
1179f4a2713aSLionel Sambuc // Write a new timestamp file so that nobody else attempts to prune.
1180f4a2713aSLionel Sambuc // There is a benign race condition here, if two Clang instances happen to
1181f4a2713aSLionel Sambuc // notice at the same time that the timestamp is out-of-date.
1182f4a2713aSLionel Sambuc writeTimestampFile(TimestampFile);
1183f4a2713aSLionel Sambuc
1184f4a2713aSLionel Sambuc // Walk the entire module cache, looking for unused module files and module
1185f4a2713aSLionel Sambuc // indices.
1186*0a6a1f1dSLionel Sambuc std::error_code EC;
1187f4a2713aSLionel Sambuc SmallString<128> ModuleCachePathNative;
1188f4a2713aSLionel Sambuc llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative);
1189f4a2713aSLionel Sambuc for (llvm::sys::fs::directory_iterator
1190f4a2713aSLionel Sambuc Dir(ModuleCachePathNative.str(), EC), DirEnd;
1191f4a2713aSLionel Sambuc Dir != DirEnd && !EC; Dir.increment(EC)) {
1192f4a2713aSLionel Sambuc // If we don't have a directory, there's nothing to look into.
1193f4a2713aSLionel Sambuc if (!llvm::sys::fs::is_directory(Dir->path()))
1194f4a2713aSLionel Sambuc continue;
1195f4a2713aSLionel Sambuc
1196f4a2713aSLionel Sambuc // Walk all of the files within this directory.
1197f4a2713aSLionel Sambuc for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd;
1198f4a2713aSLionel Sambuc File != FileEnd && !EC; File.increment(EC)) {
1199f4a2713aSLionel Sambuc // We only care about module and global module index files.
1200*0a6a1f1dSLionel Sambuc StringRef Extension = llvm::sys::path::extension(File->path());
1201*0a6a1f1dSLionel Sambuc if (Extension != ".pcm" && Extension != ".timestamp" &&
1202*0a6a1f1dSLionel Sambuc llvm::sys::path::filename(File->path()) != "modules.idx")
1203f4a2713aSLionel Sambuc continue;
1204f4a2713aSLionel Sambuc
1205f4a2713aSLionel Sambuc // Look at this file. If we can't stat it, there's nothing interesting
1206f4a2713aSLionel Sambuc // there.
1207*0a6a1f1dSLionel Sambuc if (::stat(File->path().c_str(), &StatBuf))
1208f4a2713aSLionel Sambuc continue;
1209f4a2713aSLionel Sambuc
1210f4a2713aSLionel Sambuc // If the file has been used recently enough, leave it there.
1211f4a2713aSLionel Sambuc time_t FileAccessTime = StatBuf.st_atime;
1212f4a2713aSLionel Sambuc if (CurrentTime - FileAccessTime <=
1213f4a2713aSLionel Sambuc time_t(HSOpts.ModuleCachePruneAfter)) {
1214f4a2713aSLionel Sambuc continue;
1215f4a2713aSLionel Sambuc }
1216f4a2713aSLionel Sambuc
1217f4a2713aSLionel Sambuc // Remove the file.
1218*0a6a1f1dSLionel Sambuc llvm::sys::fs::remove(File->path());
1219*0a6a1f1dSLionel Sambuc
1220*0a6a1f1dSLionel Sambuc // Remove the timestamp file.
1221*0a6a1f1dSLionel Sambuc std::string TimpestampFilename = File->path() + ".timestamp";
1222*0a6a1f1dSLionel Sambuc llvm::sys::fs::remove(TimpestampFilename);
1223f4a2713aSLionel Sambuc }
1224f4a2713aSLionel Sambuc
1225f4a2713aSLionel Sambuc // If we removed all of the files in the directory, remove the directory
1226f4a2713aSLionel Sambuc // itself.
1227*0a6a1f1dSLionel Sambuc if (llvm::sys::fs::directory_iterator(Dir->path(), EC) ==
1228*0a6a1f1dSLionel Sambuc llvm::sys::fs::directory_iterator() && !EC)
1229*0a6a1f1dSLionel Sambuc llvm::sys::fs::remove(Dir->path());
1230f4a2713aSLionel Sambuc }
1231f4a2713aSLionel Sambuc }
1232*0a6a1f1dSLionel Sambuc
createModuleManager()1233*0a6a1f1dSLionel Sambuc void CompilerInstance::createModuleManager() {
1234*0a6a1f1dSLionel Sambuc if (!ModuleManager) {
1235*0a6a1f1dSLionel Sambuc if (!hasASTContext())
1236*0a6a1f1dSLionel Sambuc createASTContext();
1237*0a6a1f1dSLionel Sambuc
1238*0a6a1f1dSLionel Sambuc // If we're not recursively building a module, check whether we
1239*0a6a1f1dSLionel Sambuc // need to prune the module cache.
1240*0a6a1f1dSLionel Sambuc if (getSourceManager().getModuleBuildStack().empty() &&
1241*0a6a1f1dSLionel Sambuc getHeaderSearchOpts().ModuleCachePruneInterval > 0 &&
1242*0a6a1f1dSLionel Sambuc getHeaderSearchOpts().ModuleCachePruneAfter > 0) {
1243*0a6a1f1dSLionel Sambuc pruneModuleCache(getHeaderSearchOpts());
1244*0a6a1f1dSLionel Sambuc }
1245*0a6a1f1dSLionel Sambuc
1246*0a6a1f1dSLionel Sambuc HeaderSearchOptions &HSOpts = getHeaderSearchOpts();
1247*0a6a1f1dSLionel Sambuc std::string Sysroot = HSOpts.Sysroot;
1248*0a6a1f1dSLionel Sambuc const PreprocessorOptions &PPOpts = getPreprocessorOpts();
1249*0a6a1f1dSLionel Sambuc ModuleManager = new ASTReader(getPreprocessor(), *Context,
1250*0a6a1f1dSLionel Sambuc Sysroot.empty() ? "" : Sysroot.c_str(),
1251*0a6a1f1dSLionel Sambuc PPOpts.DisablePCHValidation,
1252*0a6a1f1dSLionel Sambuc /*AllowASTWithCompilerErrors=*/false,
1253*0a6a1f1dSLionel Sambuc /*AllowConfigurationMismatch=*/false,
1254*0a6a1f1dSLionel Sambuc HSOpts.ModulesValidateSystemHeaders,
1255*0a6a1f1dSLionel Sambuc getFrontendOpts().UseGlobalModuleIndex);
1256*0a6a1f1dSLionel Sambuc if (hasASTConsumer()) {
1257*0a6a1f1dSLionel Sambuc ModuleManager->setDeserializationListener(
1258*0a6a1f1dSLionel Sambuc getASTConsumer().GetASTDeserializationListener());
1259*0a6a1f1dSLionel Sambuc getASTContext().setASTMutationListener(
1260*0a6a1f1dSLionel Sambuc getASTConsumer().GetASTMutationListener());
1261*0a6a1f1dSLionel Sambuc }
1262*0a6a1f1dSLionel Sambuc getASTContext().setExternalSource(ModuleManager);
1263*0a6a1f1dSLionel Sambuc if (hasSema())
1264*0a6a1f1dSLionel Sambuc ModuleManager->InitializeSema(getSema());
1265*0a6a1f1dSLionel Sambuc if (hasASTConsumer())
1266*0a6a1f1dSLionel Sambuc ModuleManager->StartTranslationUnit(&getASTConsumer());
1267*0a6a1f1dSLionel Sambuc }
1268*0a6a1f1dSLionel Sambuc }
1269*0a6a1f1dSLionel Sambuc
loadModuleFile(StringRef FileName)1270*0a6a1f1dSLionel Sambuc bool CompilerInstance::loadModuleFile(StringRef FileName) {
1271*0a6a1f1dSLionel Sambuc // Helper to recursively read the module names for all modules we're adding.
1272*0a6a1f1dSLionel Sambuc // We mark these as known and redirect any attempt to load that module to
1273*0a6a1f1dSLionel Sambuc // the files we were handed.
1274*0a6a1f1dSLionel Sambuc struct ReadModuleNames : ASTReaderListener {
1275*0a6a1f1dSLionel Sambuc CompilerInstance &CI;
1276*0a6a1f1dSLionel Sambuc std::vector<StringRef> ModuleFileStack;
1277*0a6a1f1dSLionel Sambuc bool Failed;
1278*0a6a1f1dSLionel Sambuc bool TopFileIsModule;
1279*0a6a1f1dSLionel Sambuc
1280*0a6a1f1dSLionel Sambuc ReadModuleNames(CompilerInstance &CI)
1281*0a6a1f1dSLionel Sambuc : CI(CI), Failed(false), TopFileIsModule(false) {}
1282*0a6a1f1dSLionel Sambuc
1283*0a6a1f1dSLionel Sambuc bool needsImportVisitation() const override { return true; }
1284*0a6a1f1dSLionel Sambuc
1285*0a6a1f1dSLionel Sambuc void visitImport(StringRef FileName) override {
1286*0a6a1f1dSLionel Sambuc ModuleFileStack.push_back(FileName);
1287*0a6a1f1dSLionel Sambuc if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),
1288*0a6a1f1dSLionel Sambuc *this)) {
1289*0a6a1f1dSLionel Sambuc CI.getDiagnostics().Report(SourceLocation(),
1290*0a6a1f1dSLionel Sambuc diag::err_module_file_not_found)
1291*0a6a1f1dSLionel Sambuc << FileName;
1292*0a6a1f1dSLionel Sambuc // FIXME: Produce a note stack explaining how we got here.
1293*0a6a1f1dSLionel Sambuc Failed = true;
1294*0a6a1f1dSLionel Sambuc }
1295*0a6a1f1dSLionel Sambuc ModuleFileStack.pop_back();
1296*0a6a1f1dSLionel Sambuc }
1297*0a6a1f1dSLionel Sambuc
1298*0a6a1f1dSLionel Sambuc void ReadModuleName(StringRef ModuleName) override {
1299*0a6a1f1dSLionel Sambuc if (ModuleFileStack.size() == 1)
1300*0a6a1f1dSLionel Sambuc TopFileIsModule = true;
1301*0a6a1f1dSLionel Sambuc
1302*0a6a1f1dSLionel Sambuc auto &ModuleFile = CI.ModuleFileOverrides[ModuleName];
1303*0a6a1f1dSLionel Sambuc if (!ModuleFile.empty() &&
1304*0a6a1f1dSLionel Sambuc CI.getFileManager().getFile(ModuleFile) !=
1305*0a6a1f1dSLionel Sambuc CI.getFileManager().getFile(ModuleFileStack.back()))
1306*0a6a1f1dSLionel Sambuc CI.getDiagnostics().Report(SourceLocation(),
1307*0a6a1f1dSLionel Sambuc diag::err_conflicting_module_files)
1308*0a6a1f1dSLionel Sambuc << ModuleName << ModuleFile << ModuleFileStack.back();
1309*0a6a1f1dSLionel Sambuc ModuleFile = ModuleFileStack.back();
1310*0a6a1f1dSLionel Sambuc }
1311*0a6a1f1dSLionel Sambuc } RMN(*this);
1312*0a6a1f1dSLionel Sambuc
1313*0a6a1f1dSLionel Sambuc RMN.visitImport(FileName);
1314*0a6a1f1dSLionel Sambuc
1315*0a6a1f1dSLionel Sambuc if (RMN.Failed)
1316*0a6a1f1dSLionel Sambuc return false;
1317*0a6a1f1dSLionel Sambuc
1318*0a6a1f1dSLionel Sambuc // If we never found a module name for the top file, then it's not a module,
1319*0a6a1f1dSLionel Sambuc // it's a PCH or preamble or something.
1320*0a6a1f1dSLionel Sambuc if (!RMN.TopFileIsModule) {
1321*0a6a1f1dSLionel Sambuc getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_module)
1322*0a6a1f1dSLionel Sambuc << FileName;
1323*0a6a1f1dSLionel Sambuc return false;
1324*0a6a1f1dSLionel Sambuc }
1325*0a6a1f1dSLionel Sambuc
1326*0a6a1f1dSLionel Sambuc return true;
1327f4a2713aSLionel Sambuc }
1328f4a2713aSLionel Sambuc
1329f4a2713aSLionel Sambuc ModuleLoadResult
loadModule(SourceLocation ImportLoc,ModuleIdPath Path,Module::NameVisibilityKind Visibility,bool IsInclusionDirective)1330f4a2713aSLionel Sambuc CompilerInstance::loadModule(SourceLocation ImportLoc,
1331f4a2713aSLionel Sambuc ModuleIdPath Path,
1332f4a2713aSLionel Sambuc Module::NameVisibilityKind Visibility,
1333f4a2713aSLionel Sambuc bool IsInclusionDirective) {
1334f4a2713aSLionel Sambuc // Determine what file we're searching from.
1335f4a2713aSLionel Sambuc StringRef ModuleName = Path[0].first->getName();
1336f4a2713aSLionel Sambuc SourceLocation ModuleNameLoc = Path[0].second;
1337f4a2713aSLionel Sambuc
1338f4a2713aSLionel Sambuc // If we've already handled this import, just return the cached result.
1339f4a2713aSLionel Sambuc // This one-element cache is important to eliminate redundant diagnostics
1340f4a2713aSLionel Sambuc // when both the preprocessor and parser see the same import declaration.
1341f4a2713aSLionel Sambuc if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) {
1342f4a2713aSLionel Sambuc // Make the named module visible.
1343*0a6a1f1dSLionel Sambuc if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule &&
1344*0a6a1f1dSLionel Sambuc ModuleName != getLangOpts().ImplementationOfModule)
1345f4a2713aSLionel Sambuc ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility,
1346f4a2713aSLionel Sambuc ImportLoc, /*Complain=*/false);
1347f4a2713aSLionel Sambuc return LastModuleImportResult;
1348f4a2713aSLionel Sambuc }
1349f4a2713aSLionel Sambuc
1350*0a6a1f1dSLionel Sambuc clang::Module *Module = nullptr;
1351f4a2713aSLionel Sambuc
1352f4a2713aSLionel Sambuc // If we don't already have information on this module, load the module now.
1353f4a2713aSLionel Sambuc llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known
1354f4a2713aSLionel Sambuc = KnownModules.find(Path[0].first);
1355f4a2713aSLionel Sambuc if (Known != KnownModules.end()) {
1356f4a2713aSLionel Sambuc // Retrieve the cached top-level module.
1357f4a2713aSLionel Sambuc Module = Known->second;
1358*0a6a1f1dSLionel Sambuc } else if (ModuleName == getLangOpts().CurrentModule ||
1359*0a6a1f1dSLionel Sambuc ModuleName == getLangOpts().ImplementationOfModule) {
1360f4a2713aSLionel Sambuc // This is the module we're building.
1361*0a6a1f1dSLionel Sambuc Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
1362f4a2713aSLionel Sambuc Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
1363f4a2713aSLionel Sambuc } else {
1364f4a2713aSLionel Sambuc // Search for a module with the given name.
1365f4a2713aSLionel Sambuc Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
1366f4a2713aSLionel Sambuc if (!Module) {
1367f4a2713aSLionel Sambuc getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
1368f4a2713aSLionel Sambuc << ModuleName
1369f4a2713aSLionel Sambuc << SourceRange(ImportLoc, ModuleNameLoc);
1370f4a2713aSLionel Sambuc ModuleBuildFailed = true;
1371f4a2713aSLionel Sambuc return ModuleLoadResult();
1372f4a2713aSLionel Sambuc }
1373f4a2713aSLionel Sambuc
1374*0a6a1f1dSLionel Sambuc auto Override = ModuleFileOverrides.find(ModuleName);
1375*0a6a1f1dSLionel Sambuc bool Explicit = Override != ModuleFileOverrides.end();
1376*0a6a1f1dSLionel Sambuc
1377*0a6a1f1dSLionel Sambuc std::string ModuleFileName =
1378*0a6a1f1dSLionel Sambuc Explicit ? Override->second
1379*0a6a1f1dSLionel Sambuc : PP->getHeaderSearchInfo().getModuleFileName(Module);
1380*0a6a1f1dSLionel Sambuc
1381*0a6a1f1dSLionel Sambuc // If we don't already have an ASTReader, create one now.
1382*0a6a1f1dSLionel Sambuc if (!ModuleManager)
1383*0a6a1f1dSLionel Sambuc createModuleManager();
1384*0a6a1f1dSLionel Sambuc
1385*0a6a1f1dSLionel Sambuc if (TheDependencyFileGenerator)
1386*0a6a1f1dSLionel Sambuc TheDependencyFileGenerator->AttachToASTReader(*ModuleManager);
1387*0a6a1f1dSLionel Sambuc
1388*0a6a1f1dSLionel Sambuc if (ModuleDepCollector)
1389*0a6a1f1dSLionel Sambuc ModuleDepCollector->attachToASTReader(*ModuleManager);
1390*0a6a1f1dSLionel Sambuc
1391*0a6a1f1dSLionel Sambuc for (auto &Listener : DependencyCollectors)
1392*0a6a1f1dSLionel Sambuc Listener->attachToASTReader(*ModuleManager);
1393*0a6a1f1dSLionel Sambuc
1394*0a6a1f1dSLionel Sambuc // Try to load the module file.
1395*0a6a1f1dSLionel Sambuc unsigned ARRFlags =
1396*0a6a1f1dSLionel Sambuc Explicit ? 0 : ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
1397*0a6a1f1dSLionel Sambuc switch (ModuleManager->ReadAST(ModuleFileName,
1398*0a6a1f1dSLionel Sambuc Explicit ? serialization::MK_ExplicitModule
1399*0a6a1f1dSLionel Sambuc : serialization::MK_ImplicitModule,
1400*0a6a1f1dSLionel Sambuc ImportLoc, ARRFlags)) {
1401*0a6a1f1dSLionel Sambuc case ASTReader::Success:
1402*0a6a1f1dSLionel Sambuc break;
1403*0a6a1f1dSLionel Sambuc
1404*0a6a1f1dSLionel Sambuc case ASTReader::OutOfDate:
1405*0a6a1f1dSLionel Sambuc case ASTReader::Missing: {
1406*0a6a1f1dSLionel Sambuc if (Explicit) {
1407*0a6a1f1dSLionel Sambuc // ReadAST has already complained for us.
1408*0a6a1f1dSLionel Sambuc ModuleLoader::HadFatalFailure = true;
1409*0a6a1f1dSLionel Sambuc KnownModules[Path[0].first] = nullptr;
1410*0a6a1f1dSLionel Sambuc return ModuleLoadResult();
1411*0a6a1f1dSLionel Sambuc }
1412*0a6a1f1dSLionel Sambuc
1413*0a6a1f1dSLionel Sambuc // The module file is missing or out-of-date. Build it.
1414*0a6a1f1dSLionel Sambuc assert(Module && "missing module file");
1415f4a2713aSLionel Sambuc // Check whether there is a cycle in the module graph.
1416f4a2713aSLionel Sambuc ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack();
1417f4a2713aSLionel Sambuc ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
1418f4a2713aSLionel Sambuc for (; Pos != PosEnd; ++Pos) {
1419f4a2713aSLionel Sambuc if (Pos->first == ModuleName)
1420f4a2713aSLionel Sambuc break;
1421f4a2713aSLionel Sambuc }
1422f4a2713aSLionel Sambuc
1423f4a2713aSLionel Sambuc if (Pos != PosEnd) {
1424f4a2713aSLionel Sambuc SmallString<256> CyclePath;
1425f4a2713aSLionel Sambuc for (; Pos != PosEnd; ++Pos) {
1426f4a2713aSLionel Sambuc CyclePath += Pos->first;
1427f4a2713aSLionel Sambuc CyclePath += " -> ";
1428f4a2713aSLionel Sambuc }
1429f4a2713aSLionel Sambuc CyclePath += ModuleName;
1430f4a2713aSLionel Sambuc
1431f4a2713aSLionel Sambuc getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle)
1432f4a2713aSLionel Sambuc << ModuleName << CyclePath;
1433f4a2713aSLionel Sambuc return ModuleLoadResult();
1434f4a2713aSLionel Sambuc }
1435f4a2713aSLionel Sambuc
1436f4a2713aSLionel Sambuc // Check whether we have already attempted to build this module (but
1437f4a2713aSLionel Sambuc // failed).
1438f4a2713aSLionel Sambuc if (getPreprocessorOpts().FailedModules &&
1439f4a2713aSLionel Sambuc getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) {
1440f4a2713aSLionel Sambuc getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built)
1441f4a2713aSLionel Sambuc << ModuleName
1442f4a2713aSLionel Sambuc << SourceRange(ImportLoc, ModuleNameLoc);
1443f4a2713aSLionel Sambuc ModuleBuildFailed = true;
1444f4a2713aSLionel Sambuc return ModuleLoadResult();
1445f4a2713aSLionel Sambuc }
1446f4a2713aSLionel Sambuc
1447*0a6a1f1dSLionel Sambuc // Try to compile and then load the module.
1448*0a6a1f1dSLionel Sambuc if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module,
1449*0a6a1f1dSLionel Sambuc ModuleFileName)) {
1450*0a6a1f1dSLionel Sambuc assert(getDiagnostics().hasErrorOccurred() &&
1451*0a6a1f1dSLionel Sambuc "undiagnosed error in compileAndLoadModule");
1452f4a2713aSLionel Sambuc if (getPreprocessorOpts().FailedModules)
1453f4a2713aSLionel Sambuc getPreprocessorOpts().FailedModules->addFailed(ModuleName);
1454*0a6a1f1dSLionel Sambuc KnownModules[Path[0].first] = nullptr;
1455f4a2713aSLionel Sambuc ModuleBuildFailed = true;
1456f4a2713aSLionel Sambuc return ModuleLoadResult();
1457f4a2713aSLionel Sambuc }
1458f4a2713aSLionel Sambuc
1459f4a2713aSLionel Sambuc // Okay, we've rebuilt and now loaded the module.
1460f4a2713aSLionel Sambuc break;
1461f4a2713aSLionel Sambuc }
1462f4a2713aSLionel Sambuc
1463f4a2713aSLionel Sambuc case ASTReader::VersionMismatch:
1464f4a2713aSLionel Sambuc case ASTReader::ConfigurationMismatch:
1465f4a2713aSLionel Sambuc case ASTReader::HadErrors:
1466f4a2713aSLionel Sambuc ModuleLoader::HadFatalFailure = true;
1467f4a2713aSLionel Sambuc // FIXME: The ASTReader will already have complained, but can we showhorn
1468f4a2713aSLionel Sambuc // that diagnostic information into a more useful form?
1469*0a6a1f1dSLionel Sambuc KnownModules[Path[0].first] = nullptr;
1470f4a2713aSLionel Sambuc return ModuleLoadResult();
1471f4a2713aSLionel Sambuc
1472f4a2713aSLionel Sambuc case ASTReader::Failure:
1473f4a2713aSLionel Sambuc ModuleLoader::HadFatalFailure = true;
1474f4a2713aSLionel Sambuc // Already complained, but note now that we failed.
1475*0a6a1f1dSLionel Sambuc KnownModules[Path[0].first] = nullptr;
1476f4a2713aSLionel Sambuc ModuleBuildFailed = true;
1477f4a2713aSLionel Sambuc return ModuleLoadResult();
1478f4a2713aSLionel Sambuc }
1479f4a2713aSLionel Sambuc
1480f4a2713aSLionel Sambuc // Cache the result of this top-level module lookup for later.
1481f4a2713aSLionel Sambuc Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
1482f4a2713aSLionel Sambuc }
1483f4a2713aSLionel Sambuc
1484f4a2713aSLionel Sambuc // If we never found the module, fail.
1485f4a2713aSLionel Sambuc if (!Module)
1486f4a2713aSLionel Sambuc return ModuleLoadResult();
1487f4a2713aSLionel Sambuc
1488f4a2713aSLionel Sambuc // Verify that the rest of the module path actually corresponds to
1489f4a2713aSLionel Sambuc // a submodule.
1490f4a2713aSLionel Sambuc if (Path.size() > 1) {
1491f4a2713aSLionel Sambuc for (unsigned I = 1, N = Path.size(); I != N; ++I) {
1492f4a2713aSLionel Sambuc StringRef Name = Path[I].first->getName();
1493f4a2713aSLionel Sambuc clang::Module *Sub = Module->findSubmodule(Name);
1494f4a2713aSLionel Sambuc
1495f4a2713aSLionel Sambuc if (!Sub) {
1496f4a2713aSLionel Sambuc // Attempt to perform typo correction to find a module name that works.
1497f4a2713aSLionel Sambuc SmallVector<StringRef, 2> Best;
1498f4a2713aSLionel Sambuc unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
1499f4a2713aSLionel Sambuc
1500f4a2713aSLionel Sambuc for (clang::Module::submodule_iterator J = Module->submodule_begin(),
1501f4a2713aSLionel Sambuc JEnd = Module->submodule_end();
1502f4a2713aSLionel Sambuc J != JEnd; ++J) {
1503f4a2713aSLionel Sambuc unsigned ED = Name.edit_distance((*J)->Name,
1504f4a2713aSLionel Sambuc /*AllowReplacements=*/true,
1505f4a2713aSLionel Sambuc BestEditDistance);
1506f4a2713aSLionel Sambuc if (ED <= BestEditDistance) {
1507f4a2713aSLionel Sambuc if (ED < BestEditDistance) {
1508f4a2713aSLionel Sambuc Best.clear();
1509f4a2713aSLionel Sambuc BestEditDistance = ED;
1510f4a2713aSLionel Sambuc }
1511f4a2713aSLionel Sambuc
1512f4a2713aSLionel Sambuc Best.push_back((*J)->Name);
1513f4a2713aSLionel Sambuc }
1514f4a2713aSLionel Sambuc }
1515f4a2713aSLionel Sambuc
1516f4a2713aSLionel Sambuc // If there was a clear winner, user it.
1517f4a2713aSLionel Sambuc if (Best.size() == 1) {
1518f4a2713aSLionel Sambuc getDiagnostics().Report(Path[I].second,
1519f4a2713aSLionel Sambuc diag::err_no_submodule_suggest)
1520f4a2713aSLionel Sambuc << Path[I].first << Module->getFullModuleName() << Best[0]
1521f4a2713aSLionel Sambuc << SourceRange(Path[0].second, Path[I-1].second)
1522f4a2713aSLionel Sambuc << FixItHint::CreateReplacement(SourceRange(Path[I].second),
1523f4a2713aSLionel Sambuc Best[0]);
1524f4a2713aSLionel Sambuc
1525f4a2713aSLionel Sambuc Sub = Module->findSubmodule(Best[0]);
1526f4a2713aSLionel Sambuc }
1527f4a2713aSLionel Sambuc }
1528f4a2713aSLionel Sambuc
1529f4a2713aSLionel Sambuc if (!Sub) {
1530f4a2713aSLionel Sambuc // No submodule by this name. Complain, and don't look for further
1531f4a2713aSLionel Sambuc // submodules.
1532f4a2713aSLionel Sambuc getDiagnostics().Report(Path[I].second, diag::err_no_submodule)
1533f4a2713aSLionel Sambuc << Path[I].first << Module->getFullModuleName()
1534f4a2713aSLionel Sambuc << SourceRange(Path[0].second, Path[I-1].second);
1535f4a2713aSLionel Sambuc break;
1536f4a2713aSLionel Sambuc }
1537f4a2713aSLionel Sambuc
1538f4a2713aSLionel Sambuc Module = Sub;
1539f4a2713aSLionel Sambuc }
1540f4a2713aSLionel Sambuc }
1541f4a2713aSLionel Sambuc
1542*0a6a1f1dSLionel Sambuc // Don't make the module visible if we are in the implementation.
1543*0a6a1f1dSLionel Sambuc if (ModuleName == getLangOpts().ImplementationOfModule)
1544*0a6a1f1dSLionel Sambuc return ModuleLoadResult(Module, false);
1545*0a6a1f1dSLionel Sambuc
1546f4a2713aSLionel Sambuc // Make the named module visible, if it's not already part of the module
1547f4a2713aSLionel Sambuc // we are parsing.
1548f4a2713aSLionel Sambuc if (ModuleName != getLangOpts().CurrentModule) {
1549f4a2713aSLionel Sambuc if (!Module->IsFromModuleFile) {
1550f4a2713aSLionel Sambuc // We have an umbrella header or directory that doesn't actually include
1551f4a2713aSLionel Sambuc // all of the headers within the directory it covers. Complain about
1552f4a2713aSLionel Sambuc // this missing submodule and recover by forgetting that we ever saw
1553f4a2713aSLionel Sambuc // this submodule.
1554f4a2713aSLionel Sambuc // FIXME: Should we detect this at module load time? It seems fairly
1555f4a2713aSLionel Sambuc // expensive (and rare).
1556f4a2713aSLionel Sambuc getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule)
1557f4a2713aSLionel Sambuc << Module->getFullModuleName()
1558f4a2713aSLionel Sambuc << SourceRange(Path.front().second, Path.back().second);
1559f4a2713aSLionel Sambuc
1560*0a6a1f1dSLionel Sambuc return ModuleLoadResult(nullptr, true);
1561f4a2713aSLionel Sambuc }
1562f4a2713aSLionel Sambuc
1563f4a2713aSLionel Sambuc // Check whether this module is available.
1564f4a2713aSLionel Sambuc clang::Module::Requirement Requirement;
1565*0a6a1f1dSLionel Sambuc clang::Module::UnresolvedHeaderDirective MissingHeader;
1566*0a6a1f1dSLionel Sambuc if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement,
1567*0a6a1f1dSLionel Sambuc MissingHeader)) {
1568*0a6a1f1dSLionel Sambuc if (MissingHeader.FileNameLoc.isValid()) {
1569*0a6a1f1dSLionel Sambuc getDiagnostics().Report(MissingHeader.FileNameLoc,
1570*0a6a1f1dSLionel Sambuc diag::err_module_header_missing)
1571*0a6a1f1dSLionel Sambuc << MissingHeader.IsUmbrella << MissingHeader.FileName;
1572*0a6a1f1dSLionel Sambuc } else {
1573f4a2713aSLionel Sambuc getDiagnostics().Report(ImportLoc, diag::err_module_unavailable)
1574f4a2713aSLionel Sambuc << Module->getFullModuleName()
1575f4a2713aSLionel Sambuc << Requirement.second << Requirement.first
1576f4a2713aSLionel Sambuc << SourceRange(Path.front().second, Path.back().second);
1577*0a6a1f1dSLionel Sambuc }
1578f4a2713aSLionel Sambuc LastModuleImportLoc = ImportLoc;
1579f4a2713aSLionel Sambuc LastModuleImportResult = ModuleLoadResult();
1580f4a2713aSLionel Sambuc return ModuleLoadResult();
1581f4a2713aSLionel Sambuc }
1582f4a2713aSLionel Sambuc
1583f4a2713aSLionel Sambuc ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc,
1584f4a2713aSLionel Sambuc /*Complain=*/true);
1585f4a2713aSLionel Sambuc }
1586f4a2713aSLionel Sambuc
1587f4a2713aSLionel Sambuc // Check for any configuration macros that have changed.
1588f4a2713aSLionel Sambuc clang::Module *TopModule = Module->getTopLevelModule();
1589f4a2713aSLionel Sambuc for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) {
1590f4a2713aSLionel Sambuc checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I],
1591f4a2713aSLionel Sambuc Module, ImportLoc);
1592f4a2713aSLionel Sambuc }
1593f4a2713aSLionel Sambuc
1594*0a6a1f1dSLionel Sambuc // Determine whether we're in the #include buffer for a module. The #includes
1595*0a6a1f1dSLionel Sambuc // in that buffer do not qualify as module imports; they're just an
1596*0a6a1f1dSLionel Sambuc // implementation detail of us building the module.
1597*0a6a1f1dSLionel Sambuc bool IsInModuleIncludes = !getLangOpts().CurrentModule.empty() &&
1598*0a6a1f1dSLionel Sambuc getSourceManager().getFileID(ImportLoc) ==
1599*0a6a1f1dSLionel Sambuc getSourceManager().getMainFileID();
1600*0a6a1f1dSLionel Sambuc
1601f4a2713aSLionel Sambuc // If this module import was due to an inclusion directive, create an
1602f4a2713aSLionel Sambuc // implicit import declaration to capture it in the AST.
1603*0a6a1f1dSLionel Sambuc if (IsInclusionDirective && hasASTContext() && !IsInModuleIncludes) {
1604f4a2713aSLionel Sambuc TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
1605f4a2713aSLionel Sambuc ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
1606f4a2713aSLionel Sambuc ImportLoc, Module,
1607f4a2713aSLionel Sambuc Path.back().second);
1608f4a2713aSLionel Sambuc TU->addDecl(ImportD);
1609f4a2713aSLionel Sambuc if (Consumer)
1610f4a2713aSLionel Sambuc Consumer->HandleImplicitImportDecl(ImportD);
1611f4a2713aSLionel Sambuc }
1612f4a2713aSLionel Sambuc
1613f4a2713aSLionel Sambuc LastModuleImportLoc = ImportLoc;
1614f4a2713aSLionel Sambuc LastModuleImportResult = ModuleLoadResult(Module, false);
1615f4a2713aSLionel Sambuc return LastModuleImportResult;
1616f4a2713aSLionel Sambuc }
1617f4a2713aSLionel Sambuc
makeModuleVisible(Module * Mod,Module::NameVisibilityKind Visibility,SourceLocation ImportLoc,bool Complain)1618f4a2713aSLionel Sambuc void CompilerInstance::makeModuleVisible(Module *Mod,
1619f4a2713aSLionel Sambuc Module::NameVisibilityKind Visibility,
1620f4a2713aSLionel Sambuc SourceLocation ImportLoc,
1621f4a2713aSLionel Sambuc bool Complain){
1622f4a2713aSLionel Sambuc ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc, Complain);
1623f4a2713aSLionel Sambuc }
1624f4a2713aSLionel Sambuc
loadGlobalModuleIndex(SourceLocation TriggerLoc)1625*0a6a1f1dSLionel Sambuc GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
1626*0a6a1f1dSLionel Sambuc SourceLocation TriggerLoc) {
1627*0a6a1f1dSLionel Sambuc if (!ModuleManager)
1628*0a6a1f1dSLionel Sambuc createModuleManager();
1629*0a6a1f1dSLionel Sambuc // Can't do anything if we don't have the module manager.
1630*0a6a1f1dSLionel Sambuc if (!ModuleManager)
1631*0a6a1f1dSLionel Sambuc return nullptr;
1632*0a6a1f1dSLionel Sambuc // Get an existing global index. This loads it if not already
1633*0a6a1f1dSLionel Sambuc // loaded.
1634*0a6a1f1dSLionel Sambuc ModuleManager->loadGlobalIndex();
1635*0a6a1f1dSLionel Sambuc GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1636*0a6a1f1dSLionel Sambuc // If the global index doesn't exist, create it.
1637*0a6a1f1dSLionel Sambuc if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() &&
1638*0a6a1f1dSLionel Sambuc hasPreprocessor()) {
1639*0a6a1f1dSLionel Sambuc llvm::sys::fs::create_directories(
1640*0a6a1f1dSLionel Sambuc getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
1641*0a6a1f1dSLionel Sambuc GlobalModuleIndex::writeIndex(
1642*0a6a1f1dSLionel Sambuc getFileManager(),
1643*0a6a1f1dSLionel Sambuc getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
1644*0a6a1f1dSLionel Sambuc ModuleManager->resetForReload();
1645*0a6a1f1dSLionel Sambuc ModuleManager->loadGlobalIndex();
1646*0a6a1f1dSLionel Sambuc GlobalIndex = ModuleManager->getGlobalIndex();
1647*0a6a1f1dSLionel Sambuc }
1648*0a6a1f1dSLionel Sambuc // For finding modules needing to be imported for fixit messages,
1649*0a6a1f1dSLionel Sambuc // we need to make the global index cover all modules, so we do that here.
1650*0a6a1f1dSLionel Sambuc if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) {
1651*0a6a1f1dSLionel Sambuc ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap();
1652*0a6a1f1dSLionel Sambuc bool RecreateIndex = false;
1653*0a6a1f1dSLionel Sambuc for (ModuleMap::module_iterator I = MMap.module_begin(),
1654*0a6a1f1dSLionel Sambuc E = MMap.module_end(); I != E; ++I) {
1655*0a6a1f1dSLionel Sambuc Module *TheModule = I->second;
1656*0a6a1f1dSLionel Sambuc const FileEntry *Entry = TheModule->getASTFile();
1657*0a6a1f1dSLionel Sambuc if (!Entry) {
1658*0a6a1f1dSLionel Sambuc SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
1659*0a6a1f1dSLionel Sambuc Path.push_back(std::make_pair(
1660*0a6a1f1dSLionel Sambuc getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc));
1661*0a6a1f1dSLionel Sambuc std::reverse(Path.begin(), Path.end());
1662*0a6a1f1dSLionel Sambuc // Load a module as hidden. This also adds it to the global index.
1663*0a6a1f1dSLionel Sambuc loadModule(TheModule->DefinitionLoc, Path,
1664*0a6a1f1dSLionel Sambuc Module::Hidden, false);
1665*0a6a1f1dSLionel Sambuc RecreateIndex = true;
1666*0a6a1f1dSLionel Sambuc }
1667*0a6a1f1dSLionel Sambuc }
1668*0a6a1f1dSLionel Sambuc if (RecreateIndex) {
1669*0a6a1f1dSLionel Sambuc GlobalModuleIndex::writeIndex(
1670*0a6a1f1dSLionel Sambuc getFileManager(),
1671*0a6a1f1dSLionel Sambuc getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
1672*0a6a1f1dSLionel Sambuc ModuleManager->resetForReload();
1673*0a6a1f1dSLionel Sambuc ModuleManager->loadGlobalIndex();
1674*0a6a1f1dSLionel Sambuc GlobalIndex = ModuleManager->getGlobalIndex();
1675*0a6a1f1dSLionel Sambuc }
1676*0a6a1f1dSLionel Sambuc HaveFullGlobalModuleIndex = true;
1677*0a6a1f1dSLionel Sambuc }
1678*0a6a1f1dSLionel Sambuc return GlobalIndex;
1679*0a6a1f1dSLionel Sambuc }
1680*0a6a1f1dSLionel Sambuc
1681*0a6a1f1dSLionel Sambuc // Check global module index for missing imports.
1682*0a6a1f1dSLionel Sambuc bool
lookupMissingImports(StringRef Name,SourceLocation TriggerLoc)1683*0a6a1f1dSLionel Sambuc CompilerInstance::lookupMissingImports(StringRef Name,
1684*0a6a1f1dSLionel Sambuc SourceLocation TriggerLoc) {
1685*0a6a1f1dSLionel Sambuc // Look for the symbol in non-imported modules, but only if an error
1686*0a6a1f1dSLionel Sambuc // actually occurred.
1687*0a6a1f1dSLionel Sambuc if (!buildingModule()) {
1688*0a6a1f1dSLionel Sambuc // Load global module index, or retrieve a previously loaded one.
1689*0a6a1f1dSLionel Sambuc GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex(
1690*0a6a1f1dSLionel Sambuc TriggerLoc);
1691*0a6a1f1dSLionel Sambuc
1692*0a6a1f1dSLionel Sambuc // Only if we have a global index.
1693*0a6a1f1dSLionel Sambuc if (GlobalIndex) {
1694*0a6a1f1dSLionel Sambuc GlobalModuleIndex::HitSet FoundModules;
1695*0a6a1f1dSLionel Sambuc
1696*0a6a1f1dSLionel Sambuc // Find the modules that reference the identifier.
1697*0a6a1f1dSLionel Sambuc // Note that this only finds top-level modules.
1698*0a6a1f1dSLionel Sambuc // We'll let diagnoseTypo find the actual declaration module.
1699*0a6a1f1dSLionel Sambuc if (GlobalIndex->lookupIdentifier(Name, FoundModules))
1700*0a6a1f1dSLionel Sambuc return true;
1701*0a6a1f1dSLionel Sambuc }
1702*0a6a1f1dSLionel Sambuc }
1703*0a6a1f1dSLionel Sambuc
1704*0a6a1f1dSLionel Sambuc return false;
1705*0a6a1f1dSLionel Sambuc }
resetAndLeakSema()1706*0a6a1f1dSLionel Sambuc void CompilerInstance::resetAndLeakSema() { BuryPointer(takeSema()); }
1707