blob: e8afe6dba1f4cda378d9dda9051c0942d0448a66 [file] [log] [blame]
Daniel Dunbar636404a2009-11-13 03:51:44 +00001//===--- CompilerInstance.cpp ---------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Frontend/CompilerInstance.h"
Douglas Gregor0e93f012010-08-12 23:31:19 +000011#include "clang/Sema/Sema.h"
Daniel Dunbar56d9c292009-11-14 02:47:17 +000012#include "clang/AST/ASTConsumer.h"
Daniel Dunbardf3e30c2009-11-13 08:20:47 +000013#include "clang/AST/ASTContext.h"
Douglas Gregorbcfc7d02011-12-02 23:42:12 +000014#include "clang/AST/Decl.h"
Daniel Dunbar636404a2009-11-13 03:51:44 +000015#include "clang/Basic/Diagnostic.h"
Daniel Dunbar546a6762009-11-13 04:12:06 +000016#include "clang/Basic/FileManager.h"
17#include "clang/Basic/SourceManager.h"
Daniel Dunbar636404a2009-11-13 03:51:44 +000018#include "clang/Basic/TargetInfo.h"
Daniel Dunbar4f2bc552010-01-13 00:48:06 +000019#include "clang/Basic/Version.h"
Daniel Dunbaraaa148f2009-11-13 05:52:11 +000020#include "clang/Lex/HeaderSearch.h"
21#include "clang/Lex/Preprocessor.h"
22#include "clang/Lex/PTHManager.h"
David Blaikie8b00dcb2011-09-26 00:21:47 +000023#include "clang/Frontend/ChainedDiagnosticConsumer.h"
Daniel Dunbar4f2bc552010-01-13 00:48:06 +000024#include "clang/Frontend/FrontendAction.h"
Douglas Gregorfaeb1d42011-09-12 23:31:24 +000025#include "clang/Frontend/FrontendActions.h"
Daniel Dunbarf7093b52009-11-13 09:36:05 +000026#include "clang/Frontend/FrontendDiagnostic.h"
Daniel Dunbar2083c322011-04-07 18:31:10 +000027#include "clang/Frontend/LogDiagnosticPrinter.h"
Ted Kremenek4610ea22011-10-29 00:12:39 +000028#include "clang/Frontend/SerializedDiagnosticPrinter.h"
Daniel Dunbar7d75afc2009-11-13 05:52:34 +000029#include "clang/Frontend/TextDiagnosticPrinter.h"
David Blaikie69609dc2011-09-26 00:38:03 +000030#include "clang/Frontend/VerifyDiagnosticConsumer.h"
Daniel Dunbaraaa148f2009-11-13 05:52:11 +000031#include "clang/Frontend/Utils.h"
Sebastian Redlf5b13462010-08-18 23:57:17 +000032#include "clang/Serialization/ASTReader.h"
Daniel Dunbarf7093b52009-11-13 09:36:05 +000033#include "clang/Sema/CodeCompleteConsumer.h"
Michael J. Spencerf6efe582011-01-10 02:34:13 +000034#include "llvm/Support/FileSystem.h"
Daniel Dunbar409e8902009-11-14 07:53:04 +000035#include "llvm/Support/MemoryBuffer.h"
Daniel Dunbar7d75afc2009-11-13 05:52:34 +000036#include "llvm/Support/raw_ostream.h"
Douglas Gregor171b7802010-03-30 17:33:59 +000037#include "llvm/ADT/Statistic.h"
Kovarththanan Rajaratnam5505dff2009-11-29 09:57:35 +000038#include "llvm/Support/Timer.h"
Michael J. Spencer8aaf4992010-11-29 18:12:39 +000039#include "llvm/Support/Host.h"
Douglas Gregore2124892012-01-29 20:15:24 +000040#include "llvm/Support/LockFileManager.h"
Michael J. Spencer8aaf4992010-11-29 18:12:39 +000041#include "llvm/Support/Path.h"
42#include "llvm/Support/Program.h"
43#include "llvm/Support/Signals.h"
Michael J. Spencerf25faaa2010-12-09 17:36:38 +000044#include "llvm/Support/system_error.h"
Douglas Gregor51e0b542011-10-04 00:21:21 +000045#include "llvm/Support/CrashRecoveryContext.h"
Dylan Noblesmith321cdb82011-06-23 12:20:57 +000046#include "llvm/Config/config.h"
Douglas Gregor54a88812011-10-05 14:53:30 +000047
Daniel Dunbar636404a2009-11-13 03:51:44 +000048using namespace clang;
49
Daniel Dunbare922d9b2010-02-16 01:54:47 +000050CompilerInstance::CompilerInstance()
Douglas Gregor925296b2011-07-19 16:10:42 +000051 : Invocation(new CompilerInvocation()), ModuleManager(0) {
Daniel Dunbar68242252010-01-30 21:47:07 +000052}
Daniel Dunbar636404a2009-11-13 03:51:44 +000053
54CompilerInstance::~CompilerInstance() {
Daniel Dunbare922d9b2010-02-16 01:54:47 +000055}
56
Daniel Dunbar68242252010-01-30 21:47:07 +000057void CompilerInstance::setInvocation(CompilerInvocation *Value) {
Ted Kremenek5e14d392011-03-21 18:40:17 +000058 Invocation = Value;
Daniel Dunbar68242252010-01-30 21:47:07 +000059}
60
David Blaikie9c902b52011-09-25 23:23:43 +000061void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) {
Douglas Gregor7f95d262010-04-05 23:52:57 +000062 Diagnostics = Value;
Daniel Dunbare01dc862009-11-14 01:20:40 +000063}
64
Daniel Dunbare01dc862009-11-14 01:20:40 +000065void CompilerInstance::setTarget(TargetInfo *Value) {
Ted Kremenek5e14d392011-03-21 18:40:17 +000066 Target = Value;
Daniel Dunbare01dc862009-11-14 01:20:40 +000067}
68
69void CompilerInstance::setFileManager(FileManager *Value) {
Ted Kremenek5e14d392011-03-21 18:40:17 +000070 FileMgr = Value;
Daniel Dunbare01dc862009-11-14 01:20:40 +000071}
72
NAKAMURA Takumi82a35112011-10-08 11:31:46 +000073void CompilerInstance::setSourceManager(SourceManager *Value) {
Ted Kremenek5e14d392011-03-21 18:40:17 +000074 SourceMgr = Value;
Daniel Dunbare01dc862009-11-14 01:20:40 +000075}
76
Ted Kremenek5e14d392011-03-21 18:40:17 +000077void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; }
Daniel Dunbare01dc862009-11-14 01:20:40 +000078
Ted Kremenek5e14d392011-03-21 18:40:17 +000079void CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; }
Daniel Dunbare01dc862009-11-14 01:20:40 +000080
Douglas Gregor0e93f012010-08-12 23:31:19 +000081void CompilerInstance::setSema(Sema *S) {
82 TheSema.reset(S);
83}
84
Daniel Dunbar56d9c292009-11-14 02:47:17 +000085void CompilerInstance::setASTConsumer(ASTConsumer *Value) {
86 Consumer.reset(Value);
87}
88
Daniel Dunbare01dc862009-11-14 01:20:40 +000089void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
90 CompletionConsumer.reset(Value);
91}
92
Daniel Dunbar7d75afc2009-11-13 05:52:34 +000093// Diagnostics
Daniel Dunbar7d75afc2009-11-13 05:52:34 +000094static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts,
Axel Naumann89c31492010-10-11 09:13:46 +000095 unsigned argc, const char* const *argv,
David Blaikie9c902b52011-09-25 23:23:43 +000096 DiagnosticsEngine &Diags) {
Daniel Dunbar7d75afc2009-11-13 05:52:34 +000097 std::string ErrorInfo;
Chris Lattner0e62c1c2011-07-23 10:55:15 +000098 llvm::OwningPtr<raw_ostream> OS(
Kovarththanan Rajaratnameeed0cc2010-03-17 09:47:30 +000099 new llvm::raw_fd_ostream(DiagOpts.DumpBuildInformation.c_str(), ErrorInfo));
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000100 if (!ErrorInfo.empty()) {
Kovarththanan Rajaratnam4a94ba52010-03-17 09:24:48 +0000101 Diags.Report(diag::err_fe_unable_to_open_logfile)
102 << DiagOpts.DumpBuildInformation << ErrorInfo;
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000103 return;
104 }
105
Daniel Dunbar520d1e62009-12-11 23:04:35 +0000106 (*OS) << "clang -cc1 command line arguments: ";
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000107 for (unsigned i = 0; i != argc; ++i)
108 (*OS) << argv[i] << ' ';
109 (*OS) << '\n';
110
111 // Chain in a diagnostic client which will log the diagnostics.
David Blaikiee2eefae2011-09-25 23:39:51 +0000112 DiagnosticConsumer *Logger =
Kovarththanan Rajaratnameeed0cc2010-03-17 09:47:30 +0000113 new TextDiagnosticPrinter(*OS.take(), DiagOpts, /*OwnsOutputStream=*/true);
David Blaikie8b00dcb2011-09-26 00:21:47 +0000114 Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger));
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000115}
116
Daniel Dunbar2083c322011-04-07 18:31:10 +0000117static void SetUpDiagnosticLog(const DiagnosticOptions &DiagOpts,
Daniel Dunbar7b833062011-04-07 18:59:02 +0000118 const CodeGenOptions *CodeGenOpts,
David Blaikie9c902b52011-09-25 23:23:43 +0000119 DiagnosticsEngine &Diags) {
Daniel Dunbar2083c322011-04-07 18:31:10 +0000120 std::string ErrorInfo;
121 bool OwnsStream = false;
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000122 raw_ostream *OS = &llvm::errs();
Daniel Dunbar2083c322011-04-07 18:31:10 +0000123 if (DiagOpts.DiagnosticLogFile != "-") {
124 // Create the output stream.
125 llvm::raw_fd_ostream *FileOS(
126 new llvm::raw_fd_ostream(DiagOpts.DiagnosticLogFile.c_str(),
Daniel Dunbar44d9ef72011-04-07 20:19:21 +0000127 ErrorInfo, llvm::raw_fd_ostream::F_Append));
Daniel Dunbar2083c322011-04-07 18:31:10 +0000128 if (!ErrorInfo.empty()) {
129 Diags.Report(diag::warn_fe_cc_log_diagnostics_failure)
130 << DiagOpts.DumpBuildInformation << ErrorInfo;
131 } else {
132 FileOS->SetUnbuffered();
133 FileOS->SetUseAtomicWrites(true);
134 OS = FileOS;
135 OwnsStream = true;
136 }
137 }
138
139 // Chain in the diagnostic client which will log the diagnostics.
Daniel Dunbar7b833062011-04-07 18:59:02 +0000140 LogDiagnosticPrinter *Logger = new LogDiagnosticPrinter(*OS, DiagOpts,
141 OwnsStream);
142 if (CodeGenOpts)
143 Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags);
David Blaikie8b00dcb2011-09-26 00:21:47 +0000144 Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger));
Daniel Dunbar2083c322011-04-07 18:31:10 +0000145}
146
Ted Kremenek4610ea22011-10-29 00:12:39 +0000147static void SetupSerializedDiagnostics(const DiagnosticOptions &DiagOpts,
148 DiagnosticsEngine &Diags,
149 StringRef OutputFile) {
150 std::string ErrorInfo;
151 llvm::OwningPtr<llvm::raw_fd_ostream> OS;
152 OS.reset(new llvm::raw_fd_ostream(OutputFile.str().c_str(), ErrorInfo,
153 llvm::raw_fd_ostream::F_Binary));
154
155 if (!ErrorInfo.empty()) {
156 Diags.Report(diag::warn_fe_serialized_diag_failure)
157 << OutputFile << ErrorInfo;
158 return;
159 }
160
161 DiagnosticConsumer *SerializedConsumer =
Ted Kremenek4548e042011-12-17 05:26:11 +0000162 clang::serialized_diags::create(OS.take(), DiagOpts);
Ted Kremenek4610ea22011-10-29 00:12:39 +0000163
164
165 Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(),
166 SerializedConsumer));
167}
168
Douglas Gregor44c6ee72010-11-11 00:39:14 +0000169void CompilerInstance::createDiagnostics(int Argc, const char* const *Argv,
David Blaikiee2eefae2011-09-25 23:39:51 +0000170 DiagnosticConsumer *Client,
Douglas Gregord0e9e3a2011-09-29 00:38:00 +0000171 bool ShouldOwnClient,
172 bool ShouldCloneClient) {
Daniel Dunbar7b833062011-04-07 18:59:02 +0000173 Diagnostics = createDiagnostics(getDiagnosticOpts(), Argc, Argv, Client,
Douglas Gregord0e9e3a2011-09-29 00:38:00 +0000174 ShouldOwnClient, ShouldCloneClient,
175 &getCodeGenOpts());
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000176}
177
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000178llvm::IntrusiveRefCntPtr<DiagnosticsEngine>
Douglas Gregor7f95d262010-04-05 23:52:57 +0000179CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
Douglas Gregor44c6ee72010-11-11 00:39:14 +0000180 int Argc, const char* const *Argv,
David Blaikiee2eefae2011-09-25 23:39:51 +0000181 DiagnosticConsumer *Client,
Douglas Gregor2b9b4642011-09-13 01:26:44 +0000182 bool ShouldOwnClient,
Douglas Gregord0e9e3a2011-09-29 00:38:00 +0000183 bool ShouldCloneClient,
Daniel Dunbar7b833062011-04-07 18:59:02 +0000184 const CodeGenOptions *CodeGenOpts) {
Argyrios Kyrtzidisd0040642010-11-18 20:06:41 +0000185 llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
David Blaikie9c902b52011-09-25 23:23:43 +0000186 llvm::IntrusiveRefCntPtr<DiagnosticsEngine>
187 Diags(new DiagnosticsEngine(DiagID));
Daniel Dunbar1b39a2e2009-11-14 07:53:24 +0000188
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000189 // Create the diagnostic client for reporting errors or for
190 // implementing -verify.
Douglas Gregord0e9e3a2011-09-29 00:38:00 +0000191 if (Client) {
192 if (ShouldCloneClient)
193 Diags->setClient(Client->clone(*Diags), ShouldOwnClient);
194 else
195 Diags->setClient(Client, ShouldOwnClient);
196 } else
Douglas Gregor44c6ee72010-11-11 00:39:14 +0000197 Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));
Daniel Dunbar50ec0da2009-11-14 03:24:39 +0000198
199 // Chain in -verify checker, if requested.
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000200 if (Opts.VerifyDiagnostics)
David Blaikie69609dc2011-09-26 00:38:03 +0000201 Diags->setClient(new VerifyDiagnosticConsumer(*Diags));
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000202
Daniel Dunbar2083c322011-04-07 18:31:10 +0000203 // Chain in -diagnostic-log-file dumper, if requested.
204 if (!Opts.DiagnosticLogFile.empty())
Daniel Dunbar7b833062011-04-07 18:59:02 +0000205 SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags);
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000206
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000207 if (!Opts.DumpBuildInformation.empty())
Kovarththanan Rajaratnam4a94ba52010-03-17 09:24:48 +0000208 SetUpBuildDumpLog(Opts, Argc, Argv, *Diags);
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000209
Ted Kremenek4610ea22011-10-29 00:12:39 +0000210 if (!Opts.DiagnosticSerializationFile.empty())
211 SetupSerializedDiagnostics(Opts, *Diags,
212 Opts.DiagnosticSerializationFile);
213
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000214 // Configure our handling of diagnostics.
Kovarththanan Rajaratnam9ff84d92010-03-17 09:36:02 +0000215 ProcessWarningOptions(*Diags, Opts);
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000216
Douglas Gregor7f95d262010-04-05 23:52:57 +0000217 return Diags;
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000218}
219
220// File Manager
221
Daniel Dunbar546a6762009-11-13 04:12:06 +0000222void CompilerInstance::createFileManager() {
Ted Kremenek5e14d392011-03-21 18:40:17 +0000223 FileMgr = new FileManager(getFileSystemOpts());
Daniel Dunbar546a6762009-11-13 04:12:06 +0000224}
225
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000226// Source Manager
227
Chris Lattner5159f612010-11-23 08:35:12 +0000228void CompilerInstance::createSourceManager(FileManager &FileMgr) {
Ted Kremenek5e14d392011-03-21 18:40:17 +0000229 SourceMgr = new SourceManager(getDiagnostics(), FileMgr);
Daniel Dunbar546a6762009-11-13 04:12:06 +0000230}
Daniel Dunbaraaa148f2009-11-13 05:52:11 +0000231
Daniel Dunbar7d75afc2009-11-13 05:52:34 +0000232// Preprocessor
233
Daniel Dunbaraaa148f2009-11-13 05:52:11 +0000234void CompilerInstance::createPreprocessor() {
Douglas Gregor08142532011-08-26 23:56:07 +0000235 const PreprocessorOptions &PPOpts = getPreprocessorOpts();
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000236
Daniel Dunbaraaa148f2009-11-13 05:52:11 +0000237 // Create a PTH manager if we are using some form of a token cache.
238 PTHManager *PTHMgr = 0;
Daniel Dunbard6ea9022009-11-17 05:52:41 +0000239 if (!PPOpts.TokenCache.empty())
Douglas Gregor08142532011-08-26 23:56:07 +0000240 PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics());
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000241
Daniel Dunbaraaa148f2009-11-13 05:52:11 +0000242 // Create the Preprocessor.
Douglas Gregor197ac202011-11-11 00:35:06 +0000243 HeaderSearch *HeaderInfo = new HeaderSearch(getFileManager(),
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000244 getDiagnostics(),
245 getLangOpts());
Douglas Gregor83297df2011-09-01 23:39:15 +0000246 PP = new Preprocessor(getDiagnostics(), getLangOpts(), &getTarget(),
Douglas Gregor08142532011-08-26 23:56:07 +0000247 getSourceManager(), *HeaderInfo, *this, PTHMgr,
248 /*OwnsHeaderSearch=*/true);
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000249
Daniel Dunbaraaa148f2009-11-13 05:52:11 +0000250 // Note that this is different then passing PTHMgr to Preprocessor's ctor.
251 // That argument is used as the IdentifierInfoLookup argument to
252 // IdentifierTable's ctor.
253 if (PTHMgr) {
Douglas Gregor08142532011-08-26 23:56:07 +0000254 PTHMgr->setPreprocessor(&*PP);
Daniel Dunbaraaa148f2009-11-13 05:52:11 +0000255 PP->setPTHManager(PTHMgr);
256 }
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000257
Douglas Gregor7f6d60d2010-03-19 16:15:56 +0000258 if (PPOpts.DetailedRecord)
Douglas Gregor998caea2011-05-06 16:33:08 +0000259 PP->createPreprocessingRecord(
Douglas Gregor08142532011-08-26 23:56:07 +0000260 PPOpts.DetailedRecordIncludesNestedMacroExpansions);
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000261
Douglas Gregor08142532011-08-26 23:56:07 +0000262 InitializePreprocessor(*PP, PPOpts, getHeaderSearchOpts(), getFrontendOpts());
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000263
Douglas Gregor1735f4e2011-09-13 23:15:45 +0000264 // Set up the module path, including the hash for the
265 // module-creation options.
266 llvm::SmallString<256> SpecificModuleCache(
267 getHeaderSearchOpts().ModuleCachePath);
268 if (!getHeaderSearchOpts().DisableModuleHash)
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000269 llvm::sys::path::append(SpecificModuleCache,
Douglas Gregor1735f4e2011-09-13 23:15:45 +0000270 getInvocation().getModuleHash());
Douglas Gregor2537a362011-12-08 17:01:29 +0000271 PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache);
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000272
Daniel Dunbaraaa148f2009-11-13 05:52:11 +0000273 // Handle generating dependencies, if requested.
Douglas Gregor08142532011-08-26 23:56:07 +0000274 const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
Daniel Dunbaraaa148f2009-11-13 05:52:11 +0000275 if (!DepOpts.OutputFile.empty())
276 AttachDependencyFileGen(*PP, DepOpts);
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000277
Daniel Dunbar27734fd2011-02-02 15:41:17 +0000278 // Handle generating header include information, if requested.
279 if (DepOpts.ShowHeaderIncludes)
280 AttachHeaderIncludeGen(*PP);
Daniel Dunbar1af1d27512011-02-02 21:11:31 +0000281 if (!DepOpts.HeaderIncludeOutputFile.empty()) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000282 StringRef OutputPath = DepOpts.HeaderIncludeOutputFile;
Daniel Dunbar1af1d27512011-02-02 21:11:31 +0000283 if (OutputPath == "-")
284 OutputPath = "";
Daniel Dunbarfe908a82011-03-21 19:37:38 +0000285 AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath,
286 /*ShowDepth=*/false);
Daniel Dunbar1af1d27512011-02-02 21:11:31 +0000287 }
Daniel Dunbaraaa148f2009-11-13 05:52:11 +0000288}
Daniel Dunbardf3e30c2009-11-13 08:20:47 +0000289
290// ASTContext
291
292void CompilerInstance::createASTContext() {
293 Preprocessor &PP = getPreprocessor();
Ted Kremenek5e14d392011-03-21 18:40:17 +0000294 Context = new ASTContext(getLangOpts(), PP.getSourceManager(),
Douglas Gregore8bbc122011-09-02 00:18:52 +0000295 &getTarget(), PP.getIdentifierTable(),
Ted Kremenek5e14d392011-03-21 18:40:17 +0000296 PP.getSelectorTable(), PP.getBuiltinInfo(),
297 /*size_reserve=*/ 0);
Daniel Dunbardf3e30c2009-11-13 08:20:47 +0000298}
Daniel Dunbar599313e2009-11-13 08:21:10 +0000299
300// ExternalASTSource
301
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000302void CompilerInstance::createPCHExternalASTSource(StringRef Path,
Sebastian Redl07a89a82010-07-30 00:29:29 +0000303 bool DisablePCHValidation,
Douglas Gregor606c4ac2011-02-05 19:42:43 +0000304 bool DisableStatCache,
Sebastian Redl07a89a82010-07-30 00:29:29 +0000305 void *DeserializationListener){
Daniel Dunbar599313e2009-11-13 08:21:10 +0000306 llvm::OwningPtr<ExternalASTSource> Source;
Sebastian Redl009e7f22010-10-05 16:15:19 +0000307 bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
Daniel Dunbar599313e2009-11-13 08:21:10 +0000308 Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot,
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000309 DisablePCHValidation,
Douglas Gregor606c4ac2011-02-05 19:42:43 +0000310 DisableStatCache,
Sebastian Redl07a89a82010-07-30 00:29:29 +0000311 getPreprocessor(), getASTContext(),
Sebastian Redl009e7f22010-10-05 16:15:19 +0000312 DeserializationListener,
313 Preamble));
Douglas Gregor925296b2011-07-19 16:10:42 +0000314 ModuleManager = static_cast<ASTReader*>(Source.get());
Daniel Dunbar599313e2009-11-13 08:21:10 +0000315 getASTContext().setExternalSource(Source);
316}
317
318ExternalASTSource *
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000319CompilerInstance::createPCHExternalASTSource(StringRef Path,
Daniel Dunbar599313e2009-11-13 08:21:10 +0000320 const std::string &Sysroot,
Douglas Gregorce3a8292010-07-27 00:27:13 +0000321 bool DisablePCHValidation,
Douglas Gregor606c4ac2011-02-05 19:42:43 +0000322 bool DisableStatCache,
Daniel Dunbar599313e2009-11-13 08:21:10 +0000323 Preprocessor &PP,
Sebastian Redl07a89a82010-07-30 00:29:29 +0000324 ASTContext &Context,
Sebastian Redl009e7f22010-10-05 16:15:19 +0000325 void *DeserializationListener,
326 bool Preamble) {
Sebastian Redl2c499f62010-08-18 23:56:43 +0000327 llvm::OwningPtr<ASTReader> Reader;
Douglas Gregor8835e032011-09-02 00:26:20 +0000328 Reader.reset(new ASTReader(PP, Context,
Douglas Gregorc567ba22011-07-22 16:35:34 +0000329 Sysroot.empty() ? "" : Sysroot.c_str(),
Douglas Gregor606c4ac2011-02-05 19:42:43 +0000330 DisablePCHValidation, DisableStatCache));
Daniel Dunbar599313e2009-11-13 08:21:10 +0000331
Sebastian Redl07a89a82010-07-30 00:29:29 +0000332 Reader->setDeserializationListener(
Sebastian Redl3e31c722010-08-18 23:56:56 +0000333 static_cast<ASTDeserializationListener *>(DeserializationListener));
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000334 switch (Reader->ReadAST(Path,
335 Preamble ? serialization::MK_Preamble
Douglas Gregora6895d82011-07-22 16:00:58 +0000336 : serialization::MK_PCH)) {
Sebastian Redl2c499f62010-08-18 23:56:43 +0000337 case ASTReader::Success:
Daniel Dunbar599313e2009-11-13 08:21:10 +0000338 // Set the predefines buffer as suggested by the PCH reader. Typically, the
339 // predefines buffer will be empty.
340 PP.setPredefines(Reader->getSuggestedPredefines());
341 return Reader.take();
342
Sebastian Redl2c499f62010-08-18 23:56:43 +0000343 case ASTReader::Failure:
Daniel Dunbar599313e2009-11-13 08:21:10 +0000344 // Unrecoverable failure: don't even try to process the input file.
345 break;
346
Sebastian Redl2c499f62010-08-18 23:56:43 +0000347 case ASTReader::IgnorePCH:
Daniel Dunbar599313e2009-11-13 08:21:10 +0000348 // No suitable PCH file could be found. Return an error.
349 break;
350 }
351
352 return 0;
353}
Daniel Dunbarf7093b52009-11-13 09:36:05 +0000354
355// Code Completion
356
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000357static bool EnableCodeCompletion(Preprocessor &PP,
Douglas Gregor8e984da2010-08-04 16:47:14 +0000358 const std::string &Filename,
359 unsigned Line,
360 unsigned Column) {
361 // Tell the source manager to chop off the given file at a specific
362 // line and column.
Chris Lattner5159f612010-11-23 08:35:12 +0000363 const FileEntry *Entry = PP.getFileManager().getFile(Filename);
Douglas Gregor8e984da2010-08-04 16:47:14 +0000364 if (!Entry) {
365 PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
366 << Filename;
367 return true;
368 }
369
370 // Truncate the named file at the given line/column.
371 PP.SetCodeCompletionPoint(Entry, Line, Column);
372 return false;
373}
374
Daniel Dunbarf7093b52009-11-13 09:36:05 +0000375void CompilerInstance::createCodeCompletionConsumer() {
376 const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt;
Douglas Gregor8e984da2010-08-04 16:47:14 +0000377 if (!CompletionConsumer) {
378 CompletionConsumer.reset(
379 createCodeCompletionConsumer(getPreprocessor(),
380 Loc.FileName, Loc.Line, Loc.Column,
Douglas Gregor8e984da2010-08-04 16:47:14 +0000381 getFrontendOpts().ShowMacrosInCodeCompletion,
Douglas Gregorf64acca2010-05-25 21:41:55 +0000382 getFrontendOpts().ShowCodePatternsInCodeCompletion,
Douglas Gregor39982192010-08-15 06:18:01 +0000383 getFrontendOpts().ShowGlobalSymbolsInCodeCompletion,
Douglas Gregor8e984da2010-08-04 16:47:14 +0000384 llvm::outs()));
385 if (!CompletionConsumer)
386 return;
387 } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName,
388 Loc.Line, Loc.Column)) {
389 CompletionConsumer.reset();
Douglas Gregor00a0cf72010-03-16 06:04:47 +0000390 return;
Douglas Gregor8e984da2010-08-04 16:47:14 +0000391 }
Douglas Gregorf09935f2009-12-01 05:55:20 +0000392
393 if (CompletionConsumer->isOutputBinary() &&
394 llvm::sys::Program::ChangeStdoutToBinary()) {
395 getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary);
396 CompletionConsumer.reset();
397 }
Daniel Dunbarf7093b52009-11-13 09:36:05 +0000398}
399
Kovarththanan Rajaratnam5505dff2009-11-29 09:57:35 +0000400void CompilerInstance::createFrontendTimer() {
401 FrontendTimer.reset(new llvm::Timer("Clang front-end timer"));
402}
403
Daniel Dunbarf7093b52009-11-13 09:36:05 +0000404CodeCompleteConsumer *
405CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP,
406 const std::string &Filename,
407 unsigned Line,
408 unsigned Column,
Daniel Dunbarf7093b52009-11-13 09:36:05 +0000409 bool ShowMacros,
Douglas Gregorf64acca2010-05-25 21:41:55 +0000410 bool ShowCodePatterns,
Douglas Gregor39982192010-08-15 06:18:01 +0000411 bool ShowGlobals,
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000412 raw_ostream &OS) {
Douglas Gregor8e984da2010-08-04 16:47:14 +0000413 if (EnableCodeCompletion(PP, Filename, Line, Column))
Daniel Dunbarf7093b52009-11-13 09:36:05 +0000414 return 0;
Daniel Dunbarf7093b52009-11-13 09:36:05 +0000415
416 // Set up the creation routine for code-completion.
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000417 return new PrintingCodeCompleteConsumer(ShowMacros, ShowCodePatterns,
Douglas Gregor39982192010-08-15 06:18:01 +0000418 ShowGlobals, OS);
Daniel Dunbarf7093b52009-11-13 09:36:05 +0000419}
Daniel Dunbar566eeb22009-11-13 10:37:48 +0000420
Douglas Gregor69f74f82011-08-25 22:30:56 +0000421void CompilerInstance::createSema(TranslationUnitKind TUKind,
Douglas Gregor0e93f012010-08-12 23:31:19 +0000422 CodeCompleteConsumer *CompletionConsumer) {
423 TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(),
Douglas Gregor69f74f82011-08-25 22:30:56 +0000424 TUKind, CompletionConsumer));
Douglas Gregor0e93f012010-08-12 23:31:19 +0000425}
426
Daniel Dunbar566eeb22009-11-13 10:37:48 +0000427// Output Files
428
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000429void CompilerInstance::addOutputFile(const OutputFile &OutFile) {
430 assert(OutFile.OS && "Attempt to add empty stream to output list!");
431 OutputFiles.push_back(OutFile);
Daniel Dunbar566eeb22009-11-13 10:37:48 +0000432}
433
Kovarththanan Rajaratnam1c558cd2010-03-06 12:07:48 +0000434void CompilerInstance::clearOutputFiles(bool EraseFiles) {
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000435 for (std::list<OutputFile>::iterator
Daniel Dunbar566eeb22009-11-13 10:37:48 +0000436 it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) {
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000437 delete it->OS;
438 if (!it->TempFilename.empty()) {
Anders Carlssonb5c356a2011-03-06 22:25:35 +0000439 if (EraseFiles) {
440 bool existed;
441 llvm::sys::fs::remove(it->TempFilename, existed);
442 } else {
443 llvm::SmallString<128> NewOutFile(it->Filename);
444
Argyrios Kyrtzidis71731d62010-11-03 22:45:23 +0000445 // If '-working-directory' was passed, the output filename should be
446 // relative to that.
Anders Carlsson9ba8fb12011-03-14 01:13:54 +0000447 FileMgr->FixupRelativePath(NewOutFile);
Anders Carlssonb5c356a2011-03-06 22:25:35 +0000448 if (llvm::error_code ec = llvm::sys::fs::rename(it->TempFilename,
449 NewOutFile.str())) {
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000450 getDiagnostics().Report(diag::err_fe_unable_to_rename_temp)
Anders Carlssonb5c356a2011-03-06 22:25:35 +0000451 << it->TempFilename << it->Filename << ec.message();
452
453 bool existed;
454 llvm::sys::fs::remove(it->TempFilename, existed);
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000455 }
456 }
457 } else if (!it->Filename.empty() && EraseFiles)
458 llvm::sys::Path(it->Filename).eraseFromDisk();
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000459
Daniel Dunbar566eeb22009-11-13 10:37:48 +0000460 }
461 OutputFiles.clear();
462}
463
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000464llvm::raw_fd_ostream *
465CompilerInstance::createDefaultOutputFile(bool Binary,
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000466 StringRef InFile,
467 StringRef Extension) {
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000468 return createOutputFile(getFrontendOpts().OutputFile, Binary,
Daniel Dunbare326f9b2011-01-31 22:00:42 +0000469 /*RemoveFileOnSignal=*/true, InFile, Extension);
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000470}
471
472llvm::raw_fd_ostream *
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000473CompilerInstance::createOutputFile(StringRef OutputPath,
Daniel Dunbare326f9b2011-01-31 22:00:42 +0000474 bool Binary, bool RemoveFileOnSignal,
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000475 StringRef InFile,
Argyrios Kyrtzidis08a2bfd2011-07-28 00:45:10 +0000476 StringRef Extension,
477 bool UseTemporary) {
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000478 std::string Error, OutputPathName, TempPathName;
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000479 llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary,
Daniel Dunbare326f9b2011-01-31 22:00:42 +0000480 RemoveFileOnSignal,
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000481 InFile, Extension,
Argyrios Kyrtzidis08a2bfd2011-07-28 00:45:10 +0000482 UseTemporary,
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000483 &OutputPathName,
484 &TempPathName);
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000485 if (!OS) {
Daniel Dunbar75546992009-12-03 09:13:30 +0000486 getDiagnostics().Report(diag::err_fe_unable_to_open_output)
487 << OutputPath << Error;
488 return 0;
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000489 }
490
491 // Add the output file -- but don't try to remove "-", since this means we are
492 // using stdin.
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000493 addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "",
494 TempPathName, OS));
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000495
496 return OS;
497}
498
499llvm::raw_fd_ostream *
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000500CompilerInstance::createOutputFile(StringRef OutputPath,
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000501 std::string &Error,
502 bool Binary,
Daniel Dunbare326f9b2011-01-31 22:00:42 +0000503 bool RemoveFileOnSignal,
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000504 StringRef InFile,
505 StringRef Extension,
Argyrios Kyrtzidis08a2bfd2011-07-28 00:45:10 +0000506 bool UseTemporary,
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000507 std::string *ResultPathName,
508 std::string *TempPathName) {
509 std::string OutFile, TempFile;
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000510 if (!OutputPath.empty()) {
511 OutFile = OutputPath;
512 } else if (InFile == "-") {
513 OutFile = "-";
514 } else if (!Extension.empty()) {
515 llvm::sys::Path Path(InFile);
516 Path.eraseSuffix();
517 Path.appendSuffix(Extension);
518 OutFile = Path.str();
519 } else {
520 OutFile = "-";
521 }
Argyrios Kyrtzidis08a2bfd2011-07-28 00:45:10 +0000522
523 llvm::OwningPtr<llvm::raw_fd_ostream> OS;
524 std::string OSFile;
525
526 if (UseTemporary && OutFile != "-") {
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000527 llvm::sys::Path OutPath(OutFile);
528 // Only create the temporary if we can actually write to OutPath, otherwise
529 // we want to fail early.
Michael J. Spencerf6efe582011-01-10 02:34:13 +0000530 bool Exists;
531 if ((llvm::sys::fs::exists(OutPath.str(), Exists) || !Exists) ||
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000532 (OutPath.isRegularFile() && OutPath.canWrite())) {
533 // Create a temporary file.
Argyrios Kyrtzidis08a2bfd2011-07-28 00:45:10 +0000534 llvm::SmallString<128> TempPath;
535 TempPath = OutFile;
536 TempPath += "-%%%%%%%%";
537 int fd;
538 if (llvm::sys::fs::unique_file(TempPath.str(), fd, TempPath,
539 /*makeAbsolute=*/false) == llvm::errc::success) {
540 OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true));
541 OSFile = TempFile = TempPath.str();
542 }
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000543 }
544 }
545
Argyrios Kyrtzidis08a2bfd2011-07-28 00:45:10 +0000546 if (!OS) {
547 OSFile = OutFile;
548 OS.reset(
549 new llvm::raw_fd_ostream(OSFile.c_str(), Error,
550 (Binary ? llvm::raw_fd_ostream::F_Binary : 0)));
551 if (!Error.empty())
552 return 0;
553 }
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000554
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000555 // Make sure the out stream file gets removed if we crash.
Daniel Dunbare326f9b2011-01-31 22:00:42 +0000556 if (RemoveFileOnSignal)
557 llvm::sys::RemoveFileOnSignal(llvm::sys::Path(OSFile));
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000558
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000559 if (ResultPathName)
560 *ResultPathName = OutFile;
Argyrios Kyrtzidisd0599972010-09-17 17:38:48 +0000561 if (TempPathName)
562 *TempPathName = TempFile;
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000563
Daniel Dunbar2eaef182009-11-20 22:32:38 +0000564 return OS.take();
Daniel Dunbar420b0f12009-11-13 18:32:08 +0000565}
Daniel Dunbar409e8902009-11-14 07:53:04 +0000566
567// Initialization Utilities
568
Douglas Gregora686e1b2012-01-27 19:52:33 +0000569bool CompilerInstance::InitializeSourceManager(StringRef InputFile,
570 SrcMgr::CharacteristicKind Kind){
571 return InitializeSourceManager(InputFile, Kind, getDiagnostics(),
572 getFileManager(), getSourceManager(),
573 getFrontendOpts());
Daniel Dunbar409e8902009-11-14 07:53:04 +0000574}
575
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000576bool CompilerInstance::InitializeSourceManager(StringRef InputFile,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000577 SrcMgr::CharacteristicKind Kind,
David Blaikie9c902b52011-09-25 23:23:43 +0000578 DiagnosticsEngine &Diags,
Daniel Dunbar409e8902009-11-14 07:53:04 +0000579 FileManager &FileMgr,
580 SourceManager &SourceMgr,
581 const FrontendOptions &Opts) {
Argyrios Kyrtzidis7c06d862011-09-19 20:40:35 +0000582 // Figure out where to get and map in the main file.
583 if (InputFile != "-") {
Chris Lattner5159f612010-11-23 08:35:12 +0000584 const FileEntry *File = FileMgr.getFile(InputFile);
Dan Gohman52765212010-10-26 21:13:51 +0000585 if (!File) {
Daniel Dunbar409e8902009-11-14 07:53:04 +0000586 Diags.Report(diag::err_fe_error_reading) << InputFile;
587 return false;
588 }
Douglas Gregora686e1b2012-01-27 19:52:33 +0000589 SourceMgr.createMainFileID(File, Kind);
Daniel Dunbar409e8902009-11-14 07:53:04 +0000590 } else {
Michael J. Spencerd9da7a12010-12-16 03:28:14 +0000591 llvm::OwningPtr<llvm::MemoryBuffer> SB;
592 if (llvm::MemoryBuffer::getSTDIN(SB)) {
Michael J. Spencerf25faaa2010-12-09 17:36:38 +0000593 // FIXME: Give ec.message() in this diag.
Daniel Dunbar409e8902009-11-14 07:53:04 +0000594 Diags.Report(diag::err_fe_error_reading_stdin);
595 return false;
596 }
Dan Gohman2f76cd72010-10-26 23:21:25 +0000597 const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(),
Chris Lattner5159f612010-11-23 08:35:12 +0000598 SB->getBufferSize(), 0);
Douglas Gregora686e1b2012-01-27 19:52:33 +0000599 SourceMgr.createMainFileID(File, Kind);
Michael J. Spencerd9da7a12010-12-16 03:28:14 +0000600 SourceMgr.overrideFileContents(File, SB.take());
Daniel Dunbar409e8902009-11-14 07:53:04 +0000601 }
602
Dan Gohman52765212010-10-26 21:13:51 +0000603 assert(!SourceMgr.getMainFileID().isInvalid() &&
604 "Couldn't establish MainFileID!");
Daniel Dunbar409e8902009-11-14 07:53:04 +0000605 return true;
606}
Daniel Dunbar4f2bc552010-01-13 00:48:06 +0000607
608// High-Level Operations
609
610bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
611 assert(hasDiagnostics() && "Diagnostics engine is not initialized!");
612 assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!");
613 assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!");
614
615 // FIXME: Take this as an argument, once all the APIs we used have moved to
616 // taking it as an input instead of hard-coding llvm::errs.
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000617 raw_ostream &OS = llvm::errs();
Daniel Dunbar4f2bc552010-01-13 00:48:06 +0000618
619 // Create the target instance.
620 setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), getTargetOpts()));
621 if (!hasTarget())
622 return false;
623
624 // Inform the target of the language options.
625 //
626 // FIXME: We shouldn't need to do this, the target should be immutable once
627 // created. This complexity should be lifted elsewhere.
628 getTarget().setForcedLangOptions(getLangOpts());
629
630 // Validate/process some options.
631 if (getHeaderSearchOpts().Verbose)
632 OS << "clang -cc1 version " CLANG_VERSION_STRING
633 << " based upon " << PACKAGE_STRING
Sebastian Pop8188c8a2011-11-01 21:33:06 +0000634 << " default target " << llvm::sys::getDefaultTargetTriple() << "\n";
Daniel Dunbar4f2bc552010-01-13 00:48:06 +0000635
636 if (getFrontendOpts().ShowTimers)
637 createFrontendTimer();
638
Douglas Gregor171b7802010-03-30 17:33:59 +0000639 if (getFrontendOpts().ShowStats)
640 llvm::EnableStatistics();
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000641
Daniel Dunbar4f2bc552010-01-13 00:48:06 +0000642 for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) {
Daniel Dunbaraed46fc2010-06-07 23:23:50 +0000643 // Reset the ID tables if we are reusing the SourceManager.
644 if (hasSourceManager())
645 getSourceManager().clearIDTables();
Daniel Dunbar4f2bc552010-01-13 00:48:06 +0000646
Douglas Gregor32fbe312012-01-20 16:28:04 +0000647 if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) {
Daniel Dunbar4f2bc552010-01-13 00:48:06 +0000648 Act.Execute();
649 Act.EndSourceFile();
650 }
651 }
652
Argyrios Kyrtzidis7910d7b2011-12-07 05:52:12 +0000653 // Notify the diagnostic client that all files were processed.
654 getDiagnostics().getClient()->finish();
655
Chris Lattner198cb4d2010-04-07 18:47:42 +0000656 if (getDiagnosticOpts().ShowCarets) {
Argyrios Kyrtzidisc79346a2010-11-18 20:06:46 +0000657 // We can have multiple diagnostics sharing one diagnostic client.
658 // Get the total number of warnings/errors from the client.
659 unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings();
660 unsigned NumErrors = getDiagnostics().getClient()->getNumErrors();
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000661
Chris Lattner198cb4d2010-04-07 18:47:42 +0000662 if (NumWarnings)
663 OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s");
664 if (NumWarnings && NumErrors)
665 OS << " and ";
666 if (NumErrors)
667 OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s");
668 if (NumWarnings || NumErrors)
669 OS << " generated.\n";
670 }
Daniel Dunbar4f2bc552010-01-13 00:48:06 +0000671
Daniel Dunbaraed46fc2010-06-07 23:23:50 +0000672 if (getFrontendOpts().ShowStats && hasFileManager()) {
Daniel Dunbar4f2bc552010-01-13 00:48:06 +0000673 getFileManager().PrintStats();
674 OS << "\n";
675 }
676
Argyrios Kyrtzidisbc467932010-11-18 21:13:57 +0000677 return !getDiagnostics().getClient()->getNumErrors();
Daniel Dunbar4f2bc552010-01-13 00:48:06 +0000678}
679
Douglas Gregorfaeb1d42011-09-12 23:31:24 +0000680/// \brief Determine the appropriate source input kind based on language
681/// options.
682static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) {
683 if (LangOpts.OpenCL)
684 return IK_OpenCL;
685 if (LangOpts.CUDA)
686 return IK_CUDA;
687 if (LangOpts.ObjC1)
688 return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC;
689 return LangOpts.CPlusPlus? IK_CXX : IK_C;
690}
691
Douglas Gregor51e0b542011-10-04 00:21:21 +0000692namespace {
Douglas Gregor514b6362011-11-29 19:06:37 +0000693 struct CompileModuleMapData {
694 CompilerInstance &Instance;
695 GenerateModuleAction &CreateModuleAction;
696 };
697}
698
699/// \brief Helper function that executes the module-generating action under
700/// a crash recovery context.
701static void doCompileMapModule(void *UserData) {
702 CompileModuleMapData &Data
703 = *reinterpret_cast<CompileModuleMapData *>(UserData);
704 Data.Instance.ExecuteAction(Data.CreateModuleAction);
705}
706
Douglas Gregor514b6362011-11-29 19:06:37 +0000707/// \brief Compile a module file for the given module, using the options
708/// provided by the importing compiler instance.
Douglas Gregorfaeb1d42011-09-12 23:31:24 +0000709static void compileModule(CompilerInstance &ImportingInstance,
Douglas Gregorde3ef502011-11-30 23:21:26 +0000710 Module *Module,
Douglas Gregor6dc57922011-11-29 18:31:39 +0000711 StringRef ModuleFileName) {
Douglas Gregore2124892012-01-29 20:15:24 +0000712 llvm::LockFileManager Locked(ModuleFileName);
Douglas Gregor54a88812011-10-05 14:53:30 +0000713 switch (Locked) {
Douglas Gregore2124892012-01-29 20:15:24 +0000714 case llvm::LockFileManager::LFS_Error:
Douglas Gregor54a88812011-10-05 14:53:30 +0000715 return;
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000716
Douglas Gregore2124892012-01-29 20:15:24 +0000717 case llvm::LockFileManager::LFS_Owned:
Douglas Gregor54a88812011-10-05 14:53:30 +0000718 // We're responsible for building the module ourselves. Do so below.
719 break;
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000720
Douglas Gregore2124892012-01-29 20:15:24 +0000721 case llvm::LockFileManager::LFS_Shared:
Douglas Gregor54a88812011-10-05 14:53:30 +0000722 // Someone else is responsible for building the module. Wait for them to
723 // finish.
724 Locked.waitForUnlock();
725 break;
726 }
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000727
Douglas Gregor514b6362011-11-29 19:06:37 +0000728 ModuleMap &ModMap
729 = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
730
Douglas Gregorfaeb1d42011-09-12 23:31:24 +0000731 // Construct a compiler invocation for creating this module.
732 llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation
733 (new CompilerInvocation(ImportingInstance.getInvocation()));
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000734
Douglas Gregorf545f672011-11-29 21:59:16 +0000735 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
736
Douglas Gregor44bf68d2011-09-15 20:53:28 +0000737 // For any options that aren't intended to affect how a module is built,
738 // reset them to their default values.
Ted Kremenek8cf47df2011-11-17 23:01:24 +0000739 Invocation->getLangOpts()->resetNonModularOptions();
Douglas Gregorf545f672011-11-29 21:59:16 +0000740 PPOpts.resetNonModularOptions();
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000741
Douglas Gregor7d106e42011-11-15 19:35:01 +0000742 // Note the name of the module we're building.
Douglas Gregor6dc57922011-11-29 18:31:39 +0000743 Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName();
Douglas Gregor7d106e42011-11-15 19:35:01 +0000744
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000745 // Note that this module is part of the module build path, so that we
Douglas Gregor44bf68d2011-09-15 20:53:28 +0000746 // can detect cycles in the module graph.
Douglas Gregorf545f672011-11-29 21:59:16 +0000747 PPOpts.ModuleBuildPath.push_back(Module->getTopLevelModuleName());
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000748
Douglas Gregorf545f672011-11-29 21:59:16 +0000749 // If there is a module map file, build the module using the module map.
Douglas Gregor44bf68d2011-09-15 20:53:28 +0000750 // Set up the inputs/outputs so that we build the module from its umbrella
751 // header.
Douglas Gregorfaeb1d42011-09-12 23:31:24 +0000752 FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
Douglas Gregor1735f4e2011-09-13 23:15:45 +0000753 FrontendOpts.OutputFile = ModuleFileName.str();
Douglas Gregorfaeb1d42011-09-12 23:31:24 +0000754 FrontendOpts.DisableFree = false;
755 FrontendOpts.Inputs.clear();
Douglas Gregorf545f672011-11-29 21:59:16 +0000756 InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts());
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000757
Douglas Gregorf545f672011-11-29 21:59:16 +0000758 // Get or create the module map that we'll use to build this module.
759 llvm::SmallString<128> TempModuleMapFileName;
760 if (const FileEntry *ModuleMapFile
761 = ModMap.getContainingModuleMapFile(Module)) {
762 // Use the module map where this module resides.
Douglas Gregor32fbe312012-01-20 16:28:04 +0000763 FrontendOpts.Inputs.push_back(FrontendInputFile(ModuleMapFile->getName(),
764 IK));
Douglas Gregorf545f672011-11-29 21:59:16 +0000765 } else {
766 // Create a temporary module map file.
767 TempModuleMapFileName = Module->Name;
768 TempModuleMapFileName += "-%%%%%%%%.map";
769 int FD;
770 if (llvm::sys::fs::unique_file(TempModuleMapFileName.str(), FD,
771 TempModuleMapFileName,
Douglas Gregor19f9f7b2011-12-06 22:05:29 +0000772 /*makeAbsolute=*/true)
Douglas Gregor2f554c42011-12-06 23:04:08 +0000773 != llvm::errc::success) {
Douglas Gregoree78d3e2011-12-07 00:54:14 +0000774 ImportingInstance.getDiagnostics().Report(diag::err_module_map_temp_file)
775 << TempModuleMapFileName;
Douglas Gregorf545f672011-11-29 21:59:16 +0000776 return;
Douglas Gregor2f554c42011-12-06 23:04:08 +0000777 }
Douglas Gregorf545f672011-11-29 21:59:16 +0000778 // Print the module map to this file.
779 llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true);
780 Module->print(OS);
781 FrontendOpts.Inputs.push_back(
Douglas Gregor32fbe312012-01-20 16:28:04 +0000782 FrontendInputFile(TempModuleMapFileName.str().str(), IK));
Douglas Gregorf545f672011-11-29 21:59:16 +0000783 }
784
785 // Don't free the remapped file buffers; they are owned by our caller.
786 PPOpts.RetainRemappedFileBuffers = true;
787
Douglas Gregor2b9b4642011-09-13 01:26:44 +0000788 Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
Douglas Gregor3728ea72011-09-13 23:20:27 +0000789 assert(ImportingInstance.getInvocation().getModuleHash() ==
Douglas Gregorf545f672011-11-29 21:59:16 +0000790 Invocation->getModuleHash() && "Module hash mismatch!");
791
Douglas Gregorfaeb1d42011-09-12 23:31:24 +0000792 // Construct a compiler instance that will be used to actually create the
793 // module.
794 CompilerInstance Instance;
795 Instance.setInvocation(&*Invocation);
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000796 Instance.createDiagnostics(/*argc=*/0, /*argv=*/0,
Douglas Gregor2b9b4642011-09-13 01:26:44 +0000797 &ImportingInstance.getDiagnosticClient(),
Douglas Gregord0e9e3a2011-09-29 00:38:00 +0000798 /*ShouldOwnClient=*/true,
799 /*ShouldCloneClient=*/true);
Douglas Gregorf545f672011-11-29 21:59:16 +0000800
Douglas Gregorfaeb1d42011-09-12 23:31:24 +0000801 // Construct a module-generating action.
Douglas Gregorf545f672011-11-29 21:59:16 +0000802 GenerateModuleAction CreateModuleAction;
803
Douglas Gregor51e0b542011-10-04 00:21:21 +0000804 // Execute the action to actually build the module in-place. Use a separate
805 // thread so that we get a stack large enough.
806 const unsigned ThreadStackSize = 8 << 20;
807 llvm::CrashRecoveryContext CRC;
Douglas Gregorf545f672011-11-29 21:59:16 +0000808 CompileModuleMapData Data = { Instance, CreateModuleAction };
809 CRC.RunSafelyOnThread(&doCompileMapModule, &Data, ThreadStackSize);
810
811 // Delete the temporary module map file.
812 // FIXME: Even though we're executing under crash protection, it would still
813 // be nice to do this with RemoveFileOnSignal when we can. However, that
814 // doesn't make sense for all clients, so clean this up manually.
815 if (!TempModuleMapFileName.empty())
816 llvm::sys::Path(TempModuleMapFileName).eraseFromDisk();
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000817}
Douglas Gregorfaeb1d42011-09-12 23:31:24 +0000818
Douglas Gregorde3ef502011-11-30 23:21:26 +0000819Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
Douglas Gregorff2be532011-12-01 17:11:21 +0000820 ModuleIdPath Path,
Douglas Gregorbcfc7d02011-12-02 23:42:12 +0000821 Module::NameVisibilityKind Visibility,
822 bool IsInclusionDirective) {
Douglas Gregor1805b8a2011-11-30 04:26:53 +0000823 // If we've already handled this import, just return the cached result.
824 // This one-element cache is important to eliminate redundant diagnostics
825 // when both the preprocessor and parser see the same import declaration.
Douglas Gregorff2be532011-12-01 17:11:21 +0000826 if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) {
827 // Make the named module visible.
828 if (LastModuleImportResult)
829 ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility);
Douglas Gregor69021972011-11-30 17:33:56 +0000830 return LastModuleImportResult;
Douglas Gregorff2be532011-12-01 17:11:21 +0000831 }
Douglas Gregor1805b8a2011-11-30 04:26:53 +0000832
Douglas Gregor08142532011-08-26 23:56:07 +0000833 // Determine what file we're searching from.
834 SourceManager &SourceMgr = getSourceManager();
835 SourceLocation ExpandedImportLoc = SourceMgr.getExpansionLoc(ImportLoc);
836 const FileEntry *CurFile
837 = SourceMgr.getFileEntryForID(SourceMgr.getFileID(ExpandedImportLoc));
838 if (!CurFile)
839 CurFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
840
Douglas Gregor71944202011-11-30 00:36:36 +0000841 StringRef ModuleName = Path[0].first->getName();
842 SourceLocation ModuleNameLoc = Path[0].second;
Douglas Gregor5196bc62011-11-30 04:03:44 +0000843
Douglas Gregorde3ef502011-11-30 23:21:26 +0000844 clang::Module *Module = 0;
Douglas Gregor71944202011-11-30 00:36:36 +0000845
Douglas Gregor5196bc62011-11-30 04:03:44 +0000846 // If we don't already have information on this module, load the module now.
Douglas Gregorde3ef502011-11-30 23:21:26 +0000847 llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known
Douglas Gregor69021972011-11-30 17:33:56 +0000848 = KnownModules.find(Path[0].first);
Douglas Gregor2537a362011-12-08 17:01:29 +0000849 if (Known != KnownModules.end()) {
850 // Retrieve the cached top-level module.
851 Module = Known->second;
852 } else if (ModuleName == getLangOpts().CurrentModule) {
853 // This is the module we're building.
854 Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName);
855 Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
856 } else {
Douglas Gregor5196bc62011-11-30 04:03:44 +0000857 // Search for a module with the given name.
Douglas Gregor279a6c32012-01-29 17:08:11 +0000858 Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
Douglas Gregor5196bc62011-11-30 04:03:44 +0000859 std::string ModuleFileName;
Douglas Gregor279a6c32012-01-29 17:08:11 +0000860 if (Module)
861 ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module);
862 else
863 ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName);
864
865 if (ModuleFileName.empty()) {
866 getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
867 << ModuleName
868 << SourceRange(ImportLoc, ModuleNameLoc);
869 LastModuleImportLoc = ImportLoc;
870 LastModuleImportResult = 0;
871 return 0;
872 }
873
874 const FileEntry *ModuleFile
875 = getFileManager().getFile(ModuleFileName, /*OpenFile=*/false,
876 /*CacheFailure=*/false);
Douglas Gregor5196bc62011-11-30 04:03:44 +0000877 bool BuildingModule = false;
878 if (!ModuleFile && Module) {
879 // The module is not cached, but we have a module map from which we can
880 // build the module.
881
882 // Check whether there is a cycle in the module graph.
883 SmallVectorImpl<std::string> &ModuleBuildPath
884 = getPreprocessorOpts().ModuleBuildPath;
885 SmallVectorImpl<std::string>::iterator Pos
886 = std::find(ModuleBuildPath.begin(), ModuleBuildPath.end(), ModuleName);
887 if (Pos != ModuleBuildPath.end()) {
888 llvm::SmallString<256> CyclePath;
889 for (; Pos != ModuleBuildPath.end(); ++Pos) {
890 CyclePath += *Pos;
891 CyclePath += " -> ";
892 }
893 CyclePath += ModuleName;
894
895 getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle)
896 << ModuleName << CyclePath;
897 return 0;
Douglas Gregordff0e892011-09-15 20:40:10 +0000898 }
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000899
Douglas Gregor5196bc62011-11-30 04:03:44 +0000900 getDiagnostics().Report(ModuleNameLoc, diag::warn_module_build)
901 << ModuleName;
902 BuildingModule = true;
903 compileModule(*this, Module, ModuleFileName);
904 ModuleFile = FileMgr->getFile(ModuleFileName);
905 }
906
907 if (!ModuleFile) {
908 getDiagnostics().Report(ModuleNameLoc,
909 BuildingModule? diag::err_module_not_built
910 : diag::err_module_not_found)
911 << ModuleName
912 << SourceRange(ImportLoc, ModuleNameLoc);
Douglas Gregordff0e892011-09-15 20:40:10 +0000913 return 0;
914 }
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000915
Douglas Gregor5196bc62011-11-30 04:03:44 +0000916 // If we don't already have an ASTReader, create one now.
917 if (!ModuleManager) {
918 if (!hasASTContext())
919 createASTContext();
NAKAMURA Takumi82a35112011-10-08 11:31:46 +0000920
Douglas Gregor5196bc62011-11-30 04:03:44 +0000921 std::string Sysroot = getHeaderSearchOpts().Sysroot;
922 const PreprocessorOptions &PPOpts = getPreprocessorOpts();
923 ModuleManager = new ASTReader(getPreprocessor(), *Context,
924 Sysroot.empty() ? "" : Sysroot.c_str(),
925 PPOpts.DisablePCHValidation,
926 PPOpts.DisableStatCache);
927 if (hasASTConsumer()) {
928 ModuleManager->setDeserializationListener(
929 getASTConsumer().GetASTDeserializationListener());
930 getASTContext().setASTMutationListener(
931 getASTConsumer().GetASTMutationListener());
932 }
933 llvm::OwningPtr<ExternalASTSource> Source;
934 Source.reset(ModuleManager);
935 getASTContext().setExternalSource(Source);
936 if (hasSema())
937 ModuleManager->InitializeSema(getSema());
938 if (hasASTConsumer())
939 ModuleManager->StartTranslationUnit(&getASTConsumer());
Douglas Gregor21931ef2011-09-14 23:13:09 +0000940 }
Douglas Gregor5196bc62011-11-30 04:03:44 +0000941
942 // Try to load the module we found.
943 switch (ModuleManager->ReadAST(ModuleFile->getName(),
944 serialization::MK_Module)) {
945 case ASTReader::Success:
946 break;
947
948 case ASTReader::IgnorePCH:
949 // FIXME: The ASTReader will already have complained, but can we showhorn
950 // that diagnostic information into a more useful form?
Douglas Gregor69021972011-11-30 17:33:56 +0000951 KnownModules[Path[0].first] = 0;
Douglas Gregor5196bc62011-11-30 04:03:44 +0000952 return 0;
953
954 case ASTReader::Failure:
Douglas Gregor69021972011-11-30 17:33:56 +0000955 // Already complained, but note now that we failed.
956 KnownModules[Path[0].first] = 0;
Douglas Gregor5196bc62011-11-30 04:03:44 +0000957 return 0;
958 }
959
Douglas Gregor69021972011-11-30 17:33:56 +0000960 if (!Module) {
961 // If we loaded the module directly, without finding a module map first,
962 // we'll have loaded the module's information from the module itself.
963 Module = PP->getHeaderSearchInfo().getModuleMap()
964 .findModule((Path[0].first->getName()));
965 }
966
967 // Cache the result of this top-level module lookup for later.
968 Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
Douglas Gregor08142532011-08-26 23:56:07 +0000969 }
Douglas Gregor5196bc62011-11-30 04:03:44 +0000970
Douglas Gregor69021972011-11-30 17:33:56 +0000971 // If we never found the module, fail.
972 if (!Module)
973 return 0;
974
Douglas Gregor5196bc62011-11-30 04:03:44 +0000975 // Verify that the rest of the module path actually corresponds to
976 // a submodule.
Douglas Gregor69021972011-11-30 17:33:56 +0000977 if (Path.size() > 1) {
Douglas Gregor5196bc62011-11-30 04:03:44 +0000978 for (unsigned I = 1, N = Path.size(); I != N; ++I) {
979 StringRef Name = Path[I].first->getName();
Douglas Gregoreb90e832012-01-04 23:32:19 +0000980 clang::Module *Sub = Module->findSubmodule(Name);
Douglas Gregor5196bc62011-11-30 04:03:44 +0000981
Douglas Gregoreb90e832012-01-04 23:32:19 +0000982 if (!Sub) {
Douglas Gregor5196bc62011-11-30 04:03:44 +0000983 // Attempt to perform typo correction to find a module name that works.
984 llvm::SmallVector<StringRef, 2> Best;
985 unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
986
Douglas Gregoreb90e832012-01-04 23:32:19 +0000987 for (clang::Module::submodule_iterator J = Module->submodule_begin(),
988 JEnd = Module->submodule_end();
Matt Beaumont-Gayeb44eda2011-11-30 19:41:21 +0000989 J != JEnd; ++J) {
Douglas Gregoreb90e832012-01-04 23:32:19 +0000990 unsigned ED = Name.edit_distance((*J)->Name,
Douglas Gregor5196bc62011-11-30 04:03:44 +0000991 /*AllowReplacements=*/true,
992 BestEditDistance);
993 if (ED <= BestEditDistance) {
Douglas Gregoreb90e832012-01-04 23:32:19 +0000994 if (ED < BestEditDistance) {
Douglas Gregor5196bc62011-11-30 04:03:44 +0000995 Best.clear();
Douglas Gregoreb90e832012-01-04 23:32:19 +0000996 BestEditDistance = ED;
997 }
998
999 Best.push_back((*J)->Name);
Douglas Gregor5196bc62011-11-30 04:03:44 +00001000 }
1001 }
1002
1003 // If there was a clear winner, user it.
1004 if (Best.size() == 1) {
1005 getDiagnostics().Report(Path[I].second,
1006 diag::err_no_submodule_suggest)
Douglas Gregor69021972011-11-30 17:33:56 +00001007 << Path[I].first << Module->getFullModuleName() << Best[0]
Douglas Gregor5196bc62011-11-30 04:03:44 +00001008 << SourceRange(Path[0].second, Path[I-1].second)
1009 << FixItHint::CreateReplacement(SourceRange(Path[I].second),
1010 Best[0]);
Douglas Gregoreb90e832012-01-04 23:32:19 +00001011
1012 Sub = Module->findSubmodule(Best[0]);
Douglas Gregor5196bc62011-11-30 04:03:44 +00001013 }
1014 }
1015
Douglas Gregoreb90e832012-01-04 23:32:19 +00001016 if (!Sub) {
Douglas Gregor5196bc62011-11-30 04:03:44 +00001017 // No submodule by this name. Complain, and don't look for further
1018 // submodules.
1019 getDiagnostics().Report(Path[I].second, diag::err_no_submodule)
Douglas Gregor69021972011-11-30 17:33:56 +00001020 << Path[I].first << Module->getFullModuleName()
Douglas Gregor5196bc62011-11-30 04:03:44 +00001021 << SourceRange(Path[0].second, Path[I-1].second);
1022 break;
1023 }
1024
Douglas Gregoreb90e832012-01-04 23:32:19 +00001025 Module = Sub;
Douglas Gregor5196bc62011-11-30 04:03:44 +00001026 }
Douglas Gregor08142532011-08-26 23:56:07 +00001027 }
Douglas Gregor5196bc62011-11-30 04:03:44 +00001028
Douglas Gregor2537a362011-12-08 17:01:29 +00001029 // Make the named module visible, if it's not already part of the module
1030 // we are parsing.
Douglas Gregor98a52db2011-12-20 00:28:52 +00001031 if (ModuleName != getLangOpts().CurrentModule) {
1032 if (!Module->IsFromModuleFile) {
1033 // We have an umbrella header or directory that doesn't actually include
1034 // all of the headers within the directory it covers. Complain about
1035 // this missing submodule and recover by forgetting that we ever saw
1036 // this submodule.
1037 // FIXME: Should we detect this at module load time? It seems fairly
1038 // expensive (and rare).
1039 getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule)
1040 << Module->getFullModuleName()
1041 << SourceRange(Path.front().second, Path.back().second);
1042
1043 return 0;
1044 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001045
1046 // Check whether this module is available.
1047 StringRef Feature;
1048 if (!Module->isAvailable(getLangOpts(), Feature)) {
1049 getDiagnostics().Report(ImportLoc, diag::err_module_unavailable)
1050 << Module->getFullModuleName()
1051 << Feature
1052 << SourceRange(Path.front().second, Path.back().second);
1053 LastModuleImportLoc = ImportLoc;
1054 LastModuleImportResult = 0;
1055 return 0;
1056 }
1057
Douglas Gregor2537a362011-12-08 17:01:29 +00001058 ModuleManager->makeModuleVisible(Module, Visibility);
Douglas Gregor98a52db2011-12-20 00:28:52 +00001059 }
1060
Douglas Gregorbcfc7d02011-12-02 23:42:12 +00001061 // If this module import was due to an inclusion directive, create an
1062 // implicit import declaration to capture it in the AST.
1063 if (IsInclusionDirective && hasASTContext()) {
1064 TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
1065 TU->addDecl(ImportDecl::CreateImplicit(getASTContext(), TU,
1066 ImportLoc, Module,
1067 Path.back().second));
1068 }
Douglas Gregor5196bc62011-11-30 04:03:44 +00001069
Douglas Gregor1805b8a2011-11-30 04:26:53 +00001070 LastModuleImportLoc = ImportLoc;
Douglas Gregor69021972011-11-30 17:33:56 +00001071 LastModuleImportResult = Module;
1072 return Module;
Douglas Gregor08142532011-08-26 23:56:07 +00001073}