blob: 72e79511eeb1539946fc012e9ca0086a97988242 [file] [log] [blame]
Douglas Gregora30cfe52011-11-11 19:10:28 +00001//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
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// This file defines the ModuleMap implementation, which describes the layout
11// of a module as it relates to headers.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/Lex/ModuleMap.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000015#include "clang/Basic/Diagnostic.h"
Douglas Gregor02c23eb2012-10-23 22:26:28 +000016#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000017#include "clang/Basic/FileManager.h"
18#include "clang/Basic/TargetInfo.h"
19#include "clang/Basic/TargetOptions.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000020#include "clang/Lex/LexDiagnostic.h"
21#include "clang/Lex/Lexer.h"
22#include "clang/Lex/LiteralSupport.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/ADT/StringSwitch.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000025#include "llvm/Support/Allocator.h"
Douglas Gregorac252a32011-12-06 19:39:29 +000026#include "llvm/Support/FileSystem.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000027#include "llvm/Support/Host.h"
Douglas Gregor8b6d3de2011-11-11 21:55:48 +000028#include "llvm/Support/PathV2.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000029#include "llvm/Support/raw_ostream.h"
Douglas Gregor98cfcbf2012-09-27 14:50:15 +000030#include <stdlib.h>
Douglas Gregora30cfe52011-11-11 19:10:28 +000031using namespace clang;
32
Douglas Gregor90db2602011-12-02 01:47:07 +000033Module::ExportDecl
34ModuleMap::resolveExport(Module *Mod,
35 const Module::UnresolvedExportDecl &Unresolved,
36 bool Complain) {
Douglas Gregor0adaa882011-12-05 17:28:06 +000037 // We may have just a wildcard.
38 if (Unresolved.Id.empty()) {
39 assert(Unresolved.Wildcard && "Invalid unresolved export");
40 return Module::ExportDecl(0, true);
41 }
42
Douglas Gregor90db2602011-12-02 01:47:07 +000043 // Find the starting module.
44 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
45 if (!Context) {
46 if (Complain)
47 Diags->Report(Unresolved.Id[0].second,
48 diag::err_mmap_missing_module_unqualified)
49 << Unresolved.Id[0].first << Mod->getFullModuleName();
50
51 return Module::ExportDecl();
52 }
53
54 // Dig into the module path.
55 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
56 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
57 Context);
58 if (!Sub) {
59 if (Complain)
60 Diags->Report(Unresolved.Id[I].second,
61 diag::err_mmap_missing_module_qualified)
62 << Unresolved.Id[I].first << Context->getFullModuleName()
63 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
64
65 return Module::ExportDecl();
66 }
67
68 Context = Sub;
69 }
70
71 return Module::ExportDecl(Context, Unresolved.Wildcard);
72}
73
Douglas Gregor51f564f2011-12-31 04:05:44 +000074ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
Douglas Gregordc58aa72012-01-30 06:01:29 +000075 const LangOptions &LangOpts, const TargetInfo *Target)
Douglas Gregor2f04f182012-02-02 18:42:48 +000076 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000077{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000078 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
79 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000080 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora30cfe52011-11-11 19:10:28 +000081 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
82 SourceMgr = new SourceManager(*Diags, FileMgr);
83}
84
85ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +000086 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
87 IEnd = Modules.end();
88 I != IEnd; ++I) {
89 delete I->getValue();
90 }
91
Douglas Gregora30cfe52011-11-11 19:10:28 +000092 delete SourceMgr;
93}
94
Douglas Gregordc58aa72012-01-30 06:01:29 +000095void ModuleMap::setTarget(const TargetInfo &Target) {
96 assert((!this->Target || this->Target == &Target) &&
97 "Improper target override");
98 this->Target = &Target;
99}
100
Douglas Gregor8b48e082012-10-12 21:15:50 +0000101/// \brief "Sanitize" a filename so that it can be used as an identifier.
102static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
103 SmallVectorImpl<char> &Buffer) {
104 if (Name.empty())
105 return Name;
106
107 // Check whether the filename is already an identifier; this is the common
108 // case.
109 bool isIdentifier = true;
110 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
111 if (isalpha(Name[I]) || Name[I] == '_' || (isdigit(Name[I]) && I > 0))
112 continue;
113
114 isIdentifier = false;
115 break;
116 }
117
118 if (!isIdentifier) {
119 // If we don't already have something with the form of an identifier,
120 // create a buffer with the sanitized name.
121 Buffer.clear();
122 if (isdigit(Name[0]))
123 Buffer.push_back('_');
124 Buffer.reserve(Buffer.size() + Name.size());
125 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
126 if (isalnum(Name[I]) || isspace(Name[I]))
127 Buffer.push_back(Name[I]);
128 else
129 Buffer.push_back('_');
130 }
131
132 Name = StringRef(Buffer.data(), Buffer.size());
133 }
134
135 while (llvm::StringSwitch<bool>(Name)
136#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
137#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
138#include "clang/Basic/TokenKinds.def"
139 .Default(false)) {
140 if (Name.data() != Buffer.data())
141 Buffer.append(Name.begin(), Name.end());
142 Buffer.push_back('_');
143 Name = StringRef(Buffer.data(), Buffer.size());
144 }
145
146 return Name;
147}
148
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000149Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000150 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000151 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000152 // If a header is not available, don't report that it maps to anything.
153 if (!Known->second.isAvailable())
Douglas Gregor51f564f2011-12-31 04:05:44 +0000154 return 0;
155
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000156 return Known->second.getModule();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000157 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000158
Douglas Gregoradb97992011-11-16 23:02:25 +0000159 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000160 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000161#ifdef LLVM_ON_UNIX
162 // Note: as an egregious but useful hack we use the real path here, because
163 // frameworks moving from top-level frameworks to embedded frameworks tend
164 // to be symlinked from the top-level location to the embedded location,
165 // and we need to resolve lookups as if we had found the embedded location.
166 char RealDirName[PATH_MAX];
167 StringRef DirName;
168 if (realpath(Dir->getName(), RealDirName))
169 DirName = RealDirName;
170 else
171 DirName = Dir->getName();
172#else
Douglas Gregoradb97992011-11-16 23:02:25 +0000173 StringRef DirName = Dir->getName();
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000174#endif
Douglas Gregore209e502011-12-06 01:10:29 +0000175
176 // Keep walking up the directory hierarchy, looking for a directory with
177 // an umbrella header.
178 do {
179 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
180 = UmbrellaDirs.find(Dir);
181 if (KnownDir != UmbrellaDirs.end()) {
182 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000183
184 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000185 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000186 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000187 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000188 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000189
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000190 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000191 // Infer submodules for each of the directories we found between
192 // the directory of the umbrella header and the directory where
193 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000194 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000195
Douglas Gregor6a1db482011-12-09 02:04:43 +0000196 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000197 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000198 SmallString<32> NameBuf;
199 StringRef Name = sanitizeFilenameAsIdentifier(
200 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
201 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000202 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000203 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000204
205 // Associate the module and the directory.
206 UmbrellaDirs[SkippedDirs[I-1]] = Result;
207
208 // If inferred submodules export everything they import, add a
209 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000210 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000211 Result->Exports.push_back(Module::ExportDecl(0, true));
212 }
213
214 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000215 SmallString<32> NameBuf;
216 StringRef Name = sanitizeFilenameAsIdentifier(
217 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000218 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000219 Explicit).first;
Argyrios Kyrtzidisc7782d92012-10-05 00:22:33 +0000220 Result->TopHeaders.insert(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000221
222 // If inferred submodules export everything they import, add a
223 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000224 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000225 Result->Exports.push_back(Module::ExportDecl(0, true));
226 } else {
227 // Record each of the directories we stepped through as being part of
228 // the module we found, since the umbrella header covers them all.
229 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
230 UmbrellaDirs[SkippedDirs[I]] = Result;
231 }
232
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000233 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000234
235 // If a header corresponds to an unavailable module, don't report
236 // that it maps to anything.
237 if (!Result->isAvailable())
238 return 0;
239
Douglas Gregore209e502011-12-06 01:10:29 +0000240 return Result;
241 }
242
243 SkippedDirs.push_back(Dir);
244
Douglas Gregoradb97992011-11-16 23:02:25 +0000245 // Retrieve our parent path.
246 DirName = llvm::sys::path::parent_path(DirName);
247 if (DirName.empty())
248 break;
249
250 // Resolve the parent path to a directory entry.
251 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000252 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000253
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000254 return 0;
255}
256
Douglas Gregor51f564f2011-12-31 04:05:44 +0000257bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000258 HeadersMap::iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000259 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000260 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000261
262 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000263 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000264 StringRef DirName = Dir->getName();
265
266 // Keep walking up the directory hierarchy, looking for a directory with
267 // an umbrella header.
268 do {
269 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
270 = UmbrellaDirs.find(Dir);
271 if (KnownDir != UmbrellaDirs.end()) {
272 Module *Found = KnownDir->second;
273 if (!Found->isAvailable())
274 return true;
275
276 // Search up the module stack until we find a module with an umbrella
277 // directory.
278 Module *UmbrellaModule = Found;
279 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
280 UmbrellaModule = UmbrellaModule->Parent;
281
282 if (UmbrellaModule->InferSubmodules) {
283 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
284 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000285 SmallString<32> NameBuf;
286 StringRef Name = sanitizeFilenameAsIdentifier(
287 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
288 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000289 Found = lookupModuleQualified(Name, Found);
290 if (!Found)
291 return false;
292 if (!Found->isAvailable())
293 return true;
294 }
295
296 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000297 SmallString<32> NameBuf;
298 StringRef Name = sanitizeFilenameAsIdentifier(
299 llvm::sys::path::stem(Header->getName()),
300 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000301 Found = lookupModuleQualified(Name, Found);
302 if (!Found)
303 return false;
304 }
305
306 return !Found->isAvailable();
307 }
308
309 SkippedDirs.push_back(Dir);
310
311 // Retrieve our parent path.
312 DirName = llvm::sys::path::parent_path(DirName);
313 if (DirName.empty())
314 break;
315
316 // Resolve the parent path to a directory entry.
317 Dir = SourceMgr->getFileManager().getDirectory(DirName);
318 } while (Dir);
319
320 return false;
321}
322
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000323Module *ModuleMap::findModule(StringRef Name) {
Douglas Gregor484535e2011-11-11 23:20:24 +0000324 llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
325 if (Known != Modules.end())
326 return Known->getValue();
327
328 return 0;
329}
330
Douglas Gregor90db2602011-12-02 01:47:07 +0000331Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
332 for(; Context; Context = Context->Parent) {
333 if (Module *Sub = lookupModuleQualified(Name, Context))
334 return Sub;
335 }
336
337 return findModule(Name);
338}
339
340Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
341 if (!Context)
342 return findModule(Name);
343
Douglas Gregorb7a78192012-01-04 23:32:19 +0000344 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000345}
346
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000347std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000348ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
349 bool IsExplicit) {
350 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000351 if (Module *Sub = lookupModuleQualified(Name, Parent))
352 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000353
354 // Create a new module with this name.
355 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
356 IsExplicit);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000357 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000358 Modules[Name] = Result;
359 return std::make_pair(Result, true);
360}
361
Douglas Gregor82e52372012-11-06 19:39:40 +0000362bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
363 StringRef Name, bool &IsSystem) {
364 // Check whether we have already looked into the parent directory
365 // for a module map.
366 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
367 inferred = InferredDirectories.find(ParentDir);
368 if (inferred == InferredDirectories.end())
369 return false;
370
371 if (!inferred->second.InferModules)
372 return false;
373
374 // We're allowed to infer for this directory, but make sure it's okay
375 // to infer this particular module.
376 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
377 inferred->second.ExcludedModules.end(),
378 Name) == inferred->second.ExcludedModules.end();
379
380 if (canInfer && inferred->second.InferSystemModules)
381 IsSystem = true;
382
383 return canInfer;
384}
385
Douglas Gregor8767dc22013-01-14 17:57:51 +0000386/// \brief For a framework module, infer the framework against which we
387/// should link.
388static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
389 FileManager &FileMgr) {
390 assert(Mod->IsFramework && "Can only infer linking for framework modules");
391 assert(!Mod->isSubFramework() &&
392 "Can only infer linking for top-level frameworks");
393
394 SmallString<128> LibName;
395 LibName += FrameworkDir->getName();
396 llvm::sys::path::append(LibName, Mod->Name);
397 if (FileMgr.getFile(LibName)) {
398 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
399 /*IsFramework=*/true));
400 }
401}
402
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000403Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000404ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000405 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000406 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000407 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000408 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000409 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
410 return Mod;
411
412 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000413
414 // If the framework has a parent path from which we're allowed to infer
415 // a framework module, do so.
416 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000417 // Determine whether we're allowed to infer a module map.
418 StringRef FrameworkDirName = FrameworkDir->getName();
419#ifdef LLVM_ON_UNIX
420 // Note: as an egregious but useful hack we use the real path here, because
421 // we might be looking at an embedded framework that symlinks out to a
422 // top-level framework, and we need to infer as if we were naming the
423 // top-level framework.
424 char RealFrameworkDirName[PATH_MAX];
425 if (realpath(FrameworkDir->getName(), RealFrameworkDirName))
426 FrameworkDirName = RealFrameworkDirName;
427#endif
428
Douglas Gregor82e52372012-11-06 19:39:40 +0000429 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000430 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000431 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000432 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000433 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
434 // Check whether we have already looked into the parent directory
435 // for a module map.
436 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
437 inferred = InferredDirectories.find(ParentDir);
438 if (inferred == InferredDirectories.end()) {
439 // We haven't looked here before. Load a module map, if there is
440 // one.
441 SmallString<128> ModMapPath = Parent;
442 llvm::sys::path::append(ModMapPath, "module.map");
443 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
444 parseModuleMapFile(ModMapFile);
445 inferred = InferredDirectories.find(ParentDir);
446 }
447
448 if (inferred == InferredDirectories.end())
449 inferred = InferredDirectories.insert(
450 std::make_pair(ParentDir, InferredDirectory())).first;
451 }
452
453 if (inferred->second.InferModules) {
454 // We're allowed to infer for this directory, but make sure it's okay
455 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000456 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000457 canInfer = std::find(inferred->second.ExcludedModules.begin(),
458 inferred->second.ExcludedModules.end(),
459 Name) == inferred->second.ExcludedModules.end();
460
461 if (inferred->second.InferSystemModules)
462 IsSystem = true;
463 }
464 }
465 }
466
467 // If we're not allowed to infer a framework module, don't.
468 if (!canInfer)
469 return 0;
470 }
471
472
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000473 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000474 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000475 llvm::sys::path::append(UmbrellaName, "Headers");
476 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000477 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000478
479 // FIXME: If there's no umbrella header, we could probably scan the
480 // framework to load *everything*. But, it's not clear that this is a good
481 // idea.
482 if (!UmbrellaHeader)
483 return 0;
484
Douglas Gregorac252a32011-12-06 19:39:29 +0000485 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
486 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000487 if (IsSystem)
488 Result->IsSystem = IsSystem;
489
Douglas Gregorb7a78192012-01-04 23:32:19 +0000490 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000491 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000492
Douglas Gregor489ad432011-12-08 18:00:48 +0000493 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000494 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000495 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000496 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000497
498 // export *
499 Result->Exports.push_back(Module::ExportDecl(0, true));
500
Douglas Gregore209e502011-12-06 01:10:29 +0000501 // module * { export * }
502 Result->InferSubmodules = true;
503 Result->InferExportWildcard = true;
504
Douglas Gregorac252a32011-12-06 19:39:29 +0000505 // Look for subframeworks.
506 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000507 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000508 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000509 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000510 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000511 llvm::sys::path::native(SubframeworksDirName.str(),
512 SubframeworksDirNameNative);
513 for (llvm::sys::fs::directory_iterator
514 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000515 Dir != DirEnd && !EC; Dir.increment(EC)) {
516 if (!StringRef(Dir->path()).endswith(".framework"))
517 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000518
Douglas Gregorac252a32011-12-06 19:39:29 +0000519 if (const DirectoryEntry *SubframeworkDir
520 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000521 // Note: as an egregious but useful hack, we use the real path here and
522 // check whether it is actually a subdirectory of the parent directory.
523 // This will not be the case if the 'subframework' is actually a symlink
524 // out to a top-level framework.
525#ifdef LLVM_ON_UNIX
526 char RealSubframeworkDirName[PATH_MAX];
527 if (realpath(Dir->path().c_str(), RealSubframeworkDirName)) {
528 StringRef SubframeworkDirName = RealSubframeworkDirName;
529
530 bool FoundParent = false;
531 do {
532 // Get the parent directory name.
533 SubframeworkDirName
534 = llvm::sys::path::parent_path(SubframeworkDirName);
535 if (SubframeworkDirName.empty())
536 break;
537
538 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
539 FoundParent = true;
540 break;
541 }
542 } while (true);
543
544 if (!FoundParent)
545 continue;
546 }
547#endif
548
Douglas Gregorac252a32011-12-06 19:39:29 +0000549 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000550 SmallString<32> NameBuf;
551 inferFrameworkModule(sanitizeFilenameAsIdentifier(
552 llvm::sys::path::stem(Dir->path()), NameBuf),
553 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000554 }
555 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000556
Douglas Gregor8767dc22013-01-14 17:57:51 +0000557 // If the module is a top-level framework, automatically link against the
558 // framework.
559 if (!Result->isSubFramework()) {
560 inferFrameworkLink(Result, FrameworkDir, FileMgr);
561 }
562
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000563 return Result;
564}
565
Douglas Gregore209e502011-12-06 01:10:29 +0000566void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000567 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000568 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000569 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000570}
571
Douglas Gregor77d029f2011-12-08 19:11:24 +0000572void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
573 Mod->Umbrella = UmbrellaDir;
574 UmbrellaDirs[UmbrellaDir] = Mod;
575}
576
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000577void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
578 bool Excluded) {
579 if (Excluded)
580 Mod->ExcludedHeaders.push_back(Header);
581 else
582 Mod->Headers.push_back(Header);
583 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000584}
585
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000586const FileEntry *
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000587ModuleMap::getContainingModuleMapFile(Module *Module) {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000588 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
589 return 0;
590
591 return SourceMgr->getFileEntryForID(
592 SourceMgr->getFileID(Module->DefinitionLoc));
593}
594
Douglas Gregora30cfe52011-11-11 19:10:28 +0000595void ModuleMap::dump() {
596 llvm::errs() << "Modules:";
597 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
598 MEnd = Modules.end();
599 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000600 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000601
602 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000603 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000604 H != HEnd; ++H) {
605 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000606 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000607 }
608}
609
Douglas Gregor90db2602011-12-02 01:47:07 +0000610bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
611 bool HadError = false;
612 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
613 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
614 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000615 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000616 Mod->Exports.push_back(Export);
617 else
618 HadError = true;
619 }
620 Mod->UnresolvedExports.clear();
621 return HadError;
622}
623
Douglas Gregor55988682011-12-05 16:33:54 +0000624Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
625 if (Loc.isInvalid())
626 return 0;
627
628 // Use the expansion location to determine which module we're in.
629 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
630 if (!ExpansionLoc.isFileID())
631 return 0;
632
633
634 const SourceManager &SrcMgr = Loc.getManager();
635 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000636
Douglas Gregor303aae92012-01-06 17:19:32 +0000637 while (const FileEntry *ExpansionFile
638 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
639 // Find the module that owns this header (if any).
640 if (Module *Mod = findModuleForHeader(ExpansionFile))
641 return Mod;
642
643 // No module owns this header, so look up the inclusion chain to see if
644 // any included header has an associated module.
645 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
646 if (IncludeLoc.isInvalid())
647 return 0;
648
649 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
650 }
651
652 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000653}
654
Douglas Gregora30cfe52011-11-11 19:10:28 +0000655//----------------------------------------------------------------------------//
656// Module map file parser
657//----------------------------------------------------------------------------//
658
659namespace clang {
660 /// \brief A token in a module map file.
661 struct MMToken {
662 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000663 Comma,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000664 EndOfFile,
665 HeaderKeyword,
666 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000667 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000668 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000669 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000670 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000671 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000672 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000673 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000674 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000675 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000676 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000677 StringLiteral,
678 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000679 RBrace,
680 LSquare,
681 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000682 } Kind;
683
684 unsigned Location;
685 unsigned StringLength;
686 const char *StringData;
687
688 void clear() {
689 Kind = EndOfFile;
690 Location = 0;
691 StringLength = 0;
692 StringData = 0;
693 }
694
695 bool is(TokenKind K) const { return Kind == K; }
696
697 SourceLocation getLocation() const {
698 return SourceLocation::getFromRawEncoding(Location);
699 }
700
701 StringRef getString() const {
702 return StringRef(StringData, StringLength);
703 }
704 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000705
706 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000707 struct Attributes {
708 Attributes() : IsSystem() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000709
710 /// \brief Whether this is a system module.
711 unsigned IsSystem : 1;
712 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000713
Douglas Gregor82e52372012-11-06 19:39:40 +0000714
Douglas Gregora30cfe52011-11-11 19:10:28 +0000715 class ModuleMapParser {
716 Lexer &L;
717 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000718
719 /// \brief Default target information, used only for string literal
720 /// parsing.
721 const TargetInfo *Target;
722
Douglas Gregora30cfe52011-11-11 19:10:28 +0000723 DiagnosticsEngine &Diags;
724 ModuleMap &Map;
725
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000726 /// \brief The directory that this module map resides in.
727 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000728
729 /// \brief The directory containing Clang-supplied headers.
730 const DirectoryEntry *BuiltinIncludeDir;
731
Douglas Gregora30cfe52011-11-11 19:10:28 +0000732 /// \brief Whether an error occurred.
733 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000734
Douglas Gregora30cfe52011-11-11 19:10:28 +0000735 /// \brief Stores string data for the various string literals referenced
736 /// during parsing.
737 llvm::BumpPtrAllocator StringData;
738
739 /// \brief The current token.
740 MMToken Tok;
741
742 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000743 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000744
745 /// \brief Consume the current token and return its location.
746 SourceLocation consumeToken();
747
748 /// \brief Skip tokens until we reach the a token with the given kind
749 /// (or the end of the file).
750 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000751
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000752 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000753 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000754 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000755 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000756 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000757 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000758 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000759 void parseLinkDecl();
Douglas Gregor82e52372012-11-06 19:39:40 +0000760 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000761 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000762
Douglas Gregor6a1db482011-12-09 02:04:43 +0000763 const DirectoryEntry *getOverriddenHeaderSearchDir();
764
Douglas Gregora30cfe52011-11-11 19:10:28 +0000765 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000766 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000767 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000768 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000769 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000770 const DirectoryEntry *Directory,
771 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000772 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000773 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
774 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000775 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000776 Tok.clear();
777 consumeToken();
778 }
779
780 bool parseModuleMapFile();
781 };
782}
783
784SourceLocation ModuleMapParser::consumeToken() {
785retry:
786 SourceLocation Result = Tok.getLocation();
787 Tok.clear();
788
789 Token LToken;
790 L.LexFromRawLexer(LToken);
791 Tok.Location = LToken.getLocation().getRawEncoding();
792 switch (LToken.getKind()) {
793 case tok::raw_identifier:
794 Tok.StringData = LToken.getRawIdentifierData();
795 Tok.StringLength = LToken.getLength();
796 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
797 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000798 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000799 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000800 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000801 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000802 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000803 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000804 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000805 .Case("umbrella", MMToken::UmbrellaKeyword)
806 .Default(MMToken::Identifier);
807 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000808
809 case tok::comma:
810 Tok.Kind = MMToken::Comma;
811 break;
812
Douglas Gregora30cfe52011-11-11 19:10:28 +0000813 case tok::eof:
814 Tok.Kind = MMToken::EndOfFile;
815 break;
816
817 case tok::l_brace:
818 Tok.Kind = MMToken::LBrace;
819 break;
820
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000821 case tok::l_square:
822 Tok.Kind = MMToken::LSquare;
823 break;
824
Douglas Gregor90db2602011-12-02 01:47:07 +0000825 case tok::period:
826 Tok.Kind = MMToken::Period;
827 break;
828
Douglas Gregora30cfe52011-11-11 19:10:28 +0000829 case tok::r_brace:
830 Tok.Kind = MMToken::RBrace;
831 break;
832
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000833 case tok::r_square:
834 Tok.Kind = MMToken::RSquare;
835 break;
836
Douglas Gregor90db2602011-12-02 01:47:07 +0000837 case tok::star:
838 Tok.Kind = MMToken::Star;
839 break;
840
Douglas Gregora30cfe52011-11-11 19:10:28 +0000841 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000842 if (LToken.hasUDSuffix()) {
843 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
844 HadError = true;
845 goto retry;
846 }
847
Douglas Gregora30cfe52011-11-11 19:10:28 +0000848 // Parse the string literal.
849 LangOptions LangOpts;
850 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
851 if (StringLiteral.hadError)
852 goto retry;
853
854 // Copy the string literal into our string data allocator.
855 unsigned Length = StringLiteral.GetStringLength();
856 char *Saved = StringData.Allocate<char>(Length + 1);
857 memcpy(Saved, StringLiteral.GetString().data(), Length);
858 Saved[Length] = 0;
859
860 // Form the token.
861 Tok.Kind = MMToken::StringLiteral;
862 Tok.StringData = Saved;
863 Tok.StringLength = Length;
864 break;
865 }
866
867 case tok::comment:
868 goto retry;
869
870 default:
871 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
872 HadError = true;
873 goto retry;
874 }
875
876 return Result;
877}
878
879void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
880 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000881 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000882 do {
883 switch (Tok.Kind) {
884 case MMToken::EndOfFile:
885 return;
886
887 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000888 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000889 return;
890
891 ++braceDepth;
892 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000893
894 case MMToken::LSquare:
895 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
896 return;
897
898 ++squareDepth;
899 break;
900
Douglas Gregora30cfe52011-11-11 19:10:28 +0000901 case MMToken::RBrace:
902 if (braceDepth > 0)
903 --braceDepth;
904 else if (Tok.is(K))
905 return;
906 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000907
908 case MMToken::RSquare:
909 if (squareDepth > 0)
910 --squareDepth;
911 else if (Tok.is(K))
912 return;
913 break;
914
Douglas Gregora30cfe52011-11-11 19:10:28 +0000915 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000916 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000917 return;
918 break;
919 }
920
921 consumeToken();
922 } while (true);
923}
924
Douglas Gregor587986e2011-12-07 02:23:45 +0000925/// \brief Parse a module-id.
926///
927/// module-id:
928/// identifier
929/// identifier '.' module-id
930///
931/// \returns true if an error occurred, false otherwise.
932bool ModuleMapParser::parseModuleId(ModuleId &Id) {
933 Id.clear();
934 do {
935 if (Tok.is(MMToken::Identifier)) {
936 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
937 consumeToken();
938 } else {
939 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
940 return true;
941 }
942
943 if (!Tok.is(MMToken::Period))
944 break;
945
946 consumeToken();
947 } while (true);
948
949 return false;
950}
951
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000952namespace {
953 /// \brief Enumerates the known attributes.
954 enum AttributeKind {
955 /// \brief An unknown attribute.
956 AT_unknown,
957 /// \brief The 'system' attribute.
958 AT_system
959 };
960}
961
Douglas Gregora30cfe52011-11-11 19:10:28 +0000962/// \brief Parse a module declaration.
963///
964/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000965/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
966/// { module-member* }
967///
Douglas Gregora30cfe52011-11-11 19:10:28 +0000968/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +0000969/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000970/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +0000971/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +0000972/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000973/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +0000974///
975/// submodule-declaration:
976/// module-declaration
977/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000978void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +0000979 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
980 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +0000981 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +0000982 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000983 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +0000984 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +0000985
Douglas Gregord620a842011-12-06 17:16:41 +0000986 // Parse 'explicit' keyword, if present.
987 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +0000988 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +0000989 Explicit = true;
990 }
991
992 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +0000993 if (Tok.is(MMToken::FrameworkKeyword)) {
994 consumeToken();
995 Framework = true;
996 }
Douglas Gregora30cfe52011-11-11 19:10:28 +0000997
998 // Parse 'module' keyword.
999 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001000 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001001 consumeToken();
1002 HadError = true;
1003 return;
1004 }
1005 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001006
1007 // If we have a wildcard for the module name, this is an inferred submodule.
1008 // Parse it.
1009 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001010 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001011
1012 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001013 ModuleId Id;
1014 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001015 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001016 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001017 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001018
Douglas Gregor587986e2011-12-07 02:23:45 +00001019 if (ActiveModule) {
1020 if (Id.size() > 1) {
1021 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1022 << SourceRange(Id.front().second, Id.back().second);
1023
1024 HadError = true;
1025 return;
1026 }
1027 } else if (Id.size() == 1 && Explicit) {
1028 // Top-level modules can't be explicit.
1029 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1030 Explicit = false;
1031 ExplicitLoc = SourceLocation();
1032 HadError = true;
1033 }
1034
1035 Module *PreviousActiveModule = ActiveModule;
1036 if (Id.size() > 1) {
1037 // This module map defines a submodule. Go find the module of which it
1038 // is a submodule.
1039 ActiveModule = 0;
1040 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1041 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1042 ActiveModule = Next;
1043 continue;
1044 }
1045
1046 if (ActiveModule) {
1047 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1048 << Id[I].first << ActiveModule->getTopLevelModule();
1049 } else {
1050 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1051 }
1052 HadError = true;
1053 return;
1054 }
1055 }
1056
1057 StringRef ModuleName = Id.back().first;
1058 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001059
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001060 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001061 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001062 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001063
Douglas Gregora30cfe52011-11-11 19:10:28 +00001064 // Parse the opening brace.
1065 if (!Tok.is(MMToken::LBrace)) {
1066 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1067 << ModuleName;
1068 HadError = true;
1069 return;
1070 }
1071 SourceLocation LBraceLoc = consumeToken();
1072
1073 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001074 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001075 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1076 // Skip the module definition.
1077 skipUntil(MMToken::RBrace);
1078 if (Tok.is(MMToken::RBrace))
1079 consumeToken();
1080 else {
1081 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1082 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1083 HadError = true;
1084 }
1085 return;
1086 }
1087
Douglas Gregora30cfe52011-11-11 19:10:28 +00001088 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1089 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001090 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001091
1092 // Skip the module definition.
1093 skipUntil(MMToken::RBrace);
1094 if (Tok.is(MMToken::RBrace))
1095 consumeToken();
1096
1097 HadError = true;
1098 return;
1099 }
1100
1101 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001102 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1103 Explicit).first;
1104 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001105 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001106 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001107
1108 bool Done = false;
1109 do {
1110 switch (Tok.Kind) {
1111 case MMToken::EndOfFile:
1112 case MMToken::RBrace:
1113 Done = true;
1114 break;
1115
1116 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001117 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001118 case MMToken::ModuleKeyword:
1119 parseModuleDecl();
1120 break;
1121
Douglas Gregor90db2602011-12-02 01:47:07 +00001122 case MMToken::ExportKeyword:
1123 parseExportDecl();
1124 break;
1125
Douglas Gregor51f564f2011-12-31 04:05:44 +00001126 case MMToken::RequiresKeyword:
1127 parseRequiresDecl();
1128 break;
1129
Douglas Gregor77d029f2011-12-08 19:11:24 +00001130 case MMToken::UmbrellaKeyword: {
1131 SourceLocation UmbrellaLoc = consumeToken();
1132 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001133 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001134 else
1135 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001136 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001137 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001138
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001139 case MMToken::ExcludeKeyword: {
1140 SourceLocation ExcludeLoc = consumeToken();
1141 if (Tok.is(MMToken::HeaderKeyword)) {
1142 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1143 } else {
1144 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1145 << "exclude";
1146 }
1147 break;
1148 }
1149
Douglas Gregor489ad432011-12-08 18:00:48 +00001150 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001151 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001152 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001153
1154 case MMToken::LinkKeyword:
1155 parseLinkDecl();
1156 break;
1157
Douglas Gregora30cfe52011-11-11 19:10:28 +00001158 default:
1159 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1160 consumeToken();
1161 break;
1162 }
1163 } while (!Done);
1164
1165 if (Tok.is(MMToken::RBrace))
1166 consumeToken();
1167 else {
1168 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1169 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1170 HadError = true;
1171 }
1172
Douglas Gregor8767dc22013-01-14 17:57:51 +00001173 // If the active module is a top-level framework, and there are no link
1174 // libraries, automatically link against the framework.
1175 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1176 ActiveModule->LinkLibraries.empty()) {
1177 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1178 }
1179
Douglas Gregor587986e2011-12-07 02:23:45 +00001180 // We're done parsing this module. Pop back to the previous module.
1181 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001182}
Douglas Gregord620a842011-12-06 17:16:41 +00001183
Douglas Gregor51f564f2011-12-31 04:05:44 +00001184/// \brief Parse a requires declaration.
1185///
1186/// requires-declaration:
1187/// 'requires' feature-list
1188///
1189/// feature-list:
1190/// identifier ',' feature-list
1191/// identifier
1192void ModuleMapParser::parseRequiresDecl() {
1193 assert(Tok.is(MMToken::RequiresKeyword));
1194
1195 // Parse 'requires' keyword.
1196 consumeToken();
1197
1198 // Parse the feature-list.
1199 do {
1200 if (!Tok.is(MMToken::Identifier)) {
1201 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1202 HadError = true;
1203 return;
1204 }
1205
1206 // Consume the feature name.
1207 std::string Feature = Tok.getString();
1208 consumeToken();
1209
1210 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001211 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001212
1213 if (!Tok.is(MMToken::Comma))
1214 break;
1215
1216 // Consume the comma.
1217 consumeToken();
1218 } while (true);
1219}
1220
Douglas Gregord620a842011-12-06 17:16:41 +00001221/// \brief Append to \p Paths the set of paths needed to get to the
1222/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001223static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001224 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001225 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001226 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001227 for (; Mod; Mod = Mod->Parent) {
1228 if (Mod->IsFramework)
1229 Paths.push_back(Mod->Name);
1230 }
1231
1232 if (Paths.empty())
1233 return;
1234
1235 // Add Frameworks/Name.framework for each subframework.
1236 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1237 llvm::sys::path::append(Path, "Frameworks");
1238 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1239 }
1240}
1241
Douglas Gregor2f04f182012-02-02 18:42:48 +00001242/// \brief Determine whether the given file name is the name of a builtin
1243/// header, supplied by Clang to replace, override, or augment existing system
1244/// headers.
1245static bool isBuiltinHeader(StringRef FileName) {
1246 return llvm::StringSwitch<bool>(FileName)
1247 .Case("float.h", true)
1248 .Case("iso646.h", true)
1249 .Case("limits.h", true)
1250 .Case("stdalign.h", true)
1251 .Case("stdarg.h", true)
1252 .Case("stdbool.h", true)
1253 .Case("stddef.h", true)
1254 .Case("stdint.h", true)
1255 .Case("tgmath.h", true)
1256 .Case("unwind.h", true)
1257 .Default(false);
1258}
1259
Douglas Gregora30cfe52011-11-11 19:10:28 +00001260/// \brief Parse a header declaration.
1261///
1262/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001263/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001264/// 'exclude'[opt] 'header' string-literal
1265void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1266 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001267 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001268 consumeToken();
1269
Douglas Gregor489ad432011-12-08 18:00:48 +00001270 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001271 bool Exclude = ExcludeLoc.isValid();
1272 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001273 // Parse the header name.
1274 if (!Tok.is(MMToken::StringLiteral)) {
1275 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1276 << "header";
1277 HadError = true;
1278 return;
1279 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001280 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001281 SourceLocation FileNameLoc = consumeToken();
1282
Douglas Gregor77d029f2011-12-08 19:11:24 +00001283 // Check whether we already have an umbrella.
1284 if (Umbrella && ActiveModule->Umbrella) {
1285 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1286 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001287 HadError = true;
1288 return;
1289 }
1290
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001291 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001292 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001293 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001294 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001295 if (llvm::sys::path::is_absolute(FileName)) {
1296 PathName = FileName;
1297 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001298 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1299 PathName = Dir->getName();
1300 llvm::sys::path::append(PathName, FileName);
1301 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001302 } else {
1303 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001304 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001305 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001306
Douglas Gregord620a842011-12-06 17:16:41 +00001307 if (ActiveModule->isPartOfFramework()) {
1308 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001309
1310 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001311 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001312 llvm::sys::path::append(PathName, FileName);
1313 File = SourceMgr.getFileManager().getFile(PathName);
1314
1315 if (!File) {
1316 // Check whether this file is in the private headers.
1317 PathName.resize(PathLength);
1318 llvm::sys::path::append(PathName, "PrivateHeaders");
1319 llvm::sys::path::append(PathName, FileName);
1320 File = SourceMgr.getFileManager().getFile(PathName);
1321 }
1322 } else {
1323 // Lookup for normal headers.
1324 llvm::sys::path::append(PathName, FileName);
1325 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001326
1327 // If this is a system module with a top-level header, this header
1328 // may have a counterpart (or replacement) in the set of headers
1329 // supplied by Clang. Find that builtin header.
1330 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1331 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001332 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001333 llvm::sys::path::append(BuiltinPathName, FileName);
1334 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1335
1336 // If Clang supplies this header but the underlying system does not,
1337 // just silently swap in our builtin version. Otherwise, we'll end
1338 // up adding both (later).
1339 if (!File && BuiltinFile) {
1340 File = BuiltinFile;
1341 BuiltinFile = 0;
1342 }
1343 }
Douglas Gregord620a842011-12-06 17:16:41 +00001344 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001345 }
Douglas Gregora8654052011-11-17 22:09:43 +00001346
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001347 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1348 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001349 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001350 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001351 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001352 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001353 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001354 } else if (Umbrella) {
1355 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001356 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001357 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001358 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001359 HadError = true;
1360 } else {
1361 // Record this umbrella header.
1362 Map.setUmbrellaHeader(ActiveModule, File);
1363 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001364 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001365 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001366 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001367
1368 // If there is a builtin counterpart to this file, add it now.
1369 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001370 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001371 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001372 } else if (!Exclude) {
1373 // Ignore excluded header files. They're optional anyway.
1374
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001375 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001376 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001377 HadError = true;
1378 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001379}
1380
Douglas Gregor77d029f2011-12-08 19:11:24 +00001381/// \brief Parse an umbrella directory declaration.
1382///
1383/// umbrella-dir-declaration:
1384/// umbrella string-literal
1385void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1386 // Parse the directory name.
1387 if (!Tok.is(MMToken::StringLiteral)) {
1388 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1389 << "umbrella";
1390 HadError = true;
1391 return;
1392 }
1393
1394 std::string DirName = Tok.getString();
1395 SourceLocation DirNameLoc = consumeToken();
1396
1397 // Check whether we already have an umbrella.
1398 if (ActiveModule->Umbrella) {
1399 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1400 << ActiveModule->getFullModuleName();
1401 HadError = true;
1402 return;
1403 }
1404
1405 // Look for this file.
1406 const DirectoryEntry *Dir = 0;
1407 if (llvm::sys::path::is_absolute(DirName))
1408 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1409 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001410 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001411 PathName = Directory->getName();
1412 llvm::sys::path::append(PathName, DirName);
1413 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1414 }
1415
1416 if (!Dir) {
1417 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1418 << DirName;
1419 HadError = true;
1420 return;
1421 }
1422
1423 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1424 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1425 << OwningModule->getFullModuleName();
1426 HadError = true;
1427 return;
1428 }
1429
1430 // Record this umbrella directory.
1431 Map.setUmbrellaDir(ActiveModule, Dir);
1432}
1433
Douglas Gregor90db2602011-12-02 01:47:07 +00001434/// \brief Parse a module export declaration.
1435///
1436/// export-declaration:
1437/// 'export' wildcard-module-id
1438///
1439/// wildcard-module-id:
1440/// identifier
1441/// '*'
1442/// identifier '.' wildcard-module-id
1443void ModuleMapParser::parseExportDecl() {
1444 assert(Tok.is(MMToken::ExportKeyword));
1445 SourceLocation ExportLoc = consumeToken();
1446
1447 // Parse the module-id with an optional wildcard at the end.
1448 ModuleId ParsedModuleId;
1449 bool Wildcard = false;
1450 do {
1451 if (Tok.is(MMToken::Identifier)) {
1452 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1453 Tok.getLocation()));
1454 consumeToken();
1455
1456 if (Tok.is(MMToken::Period)) {
1457 consumeToken();
1458 continue;
1459 }
1460
1461 break;
1462 }
1463
1464 if(Tok.is(MMToken::Star)) {
1465 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001466 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001467 break;
1468 }
1469
1470 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1471 HadError = true;
1472 return;
1473 } while (true);
1474
1475 Module::UnresolvedExportDecl Unresolved = {
1476 ExportLoc, ParsedModuleId, Wildcard
1477 };
1478 ActiveModule->UnresolvedExports.push_back(Unresolved);
1479}
1480
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001481/// \brief Parse a link declaration.
1482///
1483/// module-declaration:
1484/// 'link' 'framework'[opt] string-literal
1485void ModuleMapParser::parseLinkDecl() {
1486 assert(Tok.is(MMToken::LinkKeyword));
1487 SourceLocation LinkLoc = consumeToken();
1488
1489 // Parse the optional 'framework' keyword.
1490 bool IsFramework = false;
1491 if (Tok.is(MMToken::FrameworkKeyword)) {
1492 consumeToken();
1493 IsFramework = true;
1494 }
1495
1496 // Parse the library name
1497 if (!Tok.is(MMToken::StringLiteral)) {
1498 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1499 << IsFramework << SourceRange(LinkLoc);
1500 HadError = true;
1501 return;
1502 }
1503
1504 std::string LibraryName = Tok.getString();
1505 consumeToken();
1506 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1507 IsFramework));
1508}
1509
1510/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001511///
1512/// module-declaration:
1513/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1514/// { inferred-module-member* }
1515///
1516/// inferred-module-member:
1517/// 'export' '*'
1518/// 'exclude' identifier
1519void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001520 assert(Tok.is(MMToken::Star));
1521 SourceLocation StarLoc = consumeToken();
1522 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001523
Douglas Gregor1e123682011-12-05 22:27:44 +00001524 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001525 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001526 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1527 Failed = true;
1528 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001529
1530 if (ActiveModule) {
1531 // Inferred modules must have umbrella directories.
1532 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1533 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1534 Failed = true;
1535 }
1536
1537 // Check for redefinition of an inferred module.
1538 if (!Failed && ActiveModule->InferSubmodules) {
1539 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1540 if (ActiveModule->InferredSubmoduleLoc.isValid())
1541 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1542 diag::note_mmap_prev_definition);
1543 Failed = true;
1544 }
1545
1546 // Check for the 'framework' keyword, which is not permitted here.
1547 if (Framework) {
1548 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1549 Framework = false;
1550 }
1551 } else if (Explicit) {
1552 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1553 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001554 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001555
Douglas Gregor1e123682011-12-05 22:27:44 +00001556 // If there were any problems with this inferred submodule, skip its body.
1557 if (Failed) {
1558 if (Tok.is(MMToken::LBrace)) {
1559 consumeToken();
1560 skipUntil(MMToken::RBrace);
1561 if (Tok.is(MMToken::RBrace))
1562 consumeToken();
1563 }
1564 HadError = true;
1565 return;
1566 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001567
1568 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001569 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001570 parseOptionalAttributes(Attrs);
1571
1572 if (ActiveModule) {
1573 // Note that we have an inferred submodule.
1574 ActiveModule->InferSubmodules = true;
1575 ActiveModule->InferredSubmoduleLoc = StarLoc;
1576 ActiveModule->InferExplicitSubmodules = Explicit;
1577 } else {
1578 // We'll be inferring framework modules for this directory.
1579 Map.InferredDirectories[Directory].InferModules = true;
1580 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1581 }
1582
Douglas Gregor1e123682011-12-05 22:27:44 +00001583 // Parse the opening brace.
1584 if (!Tok.is(MMToken::LBrace)) {
1585 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1586 HadError = true;
1587 return;
1588 }
1589 SourceLocation LBraceLoc = consumeToken();
1590
1591 // Parse the body of the inferred submodule.
1592 bool Done = false;
1593 do {
1594 switch (Tok.Kind) {
1595 case MMToken::EndOfFile:
1596 case MMToken::RBrace:
1597 Done = true;
1598 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001599
1600 case MMToken::ExcludeKeyword: {
1601 if (ActiveModule) {
1602 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001603 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001604 consumeToken();
1605 break;
1606 }
1607
1608 consumeToken();
1609 if (!Tok.is(MMToken::Identifier)) {
1610 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1611 break;
1612 }
1613
1614 Map.InferredDirectories[Directory].ExcludedModules
1615 .push_back(Tok.getString());
1616 consumeToken();
1617 break;
1618 }
1619
1620 case MMToken::ExportKeyword:
1621 if (!ActiveModule) {
1622 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001623 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001624 consumeToken();
1625 break;
1626 }
1627
Douglas Gregor1e123682011-12-05 22:27:44 +00001628 consumeToken();
1629 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001630 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001631 else
1632 Diags.Report(Tok.getLocation(),
1633 diag::err_mmap_expected_export_wildcard);
1634 consumeToken();
1635 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001636
Douglas Gregor1e123682011-12-05 22:27:44 +00001637 case MMToken::ExplicitKeyword:
1638 case MMToken::ModuleKeyword:
1639 case MMToken::HeaderKeyword:
1640 case MMToken::UmbrellaKeyword:
1641 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001642 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001643 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001644 consumeToken();
1645 break;
1646 }
1647 } while (!Done);
1648
1649 if (Tok.is(MMToken::RBrace))
1650 consumeToken();
1651 else {
1652 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1653 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1654 HadError = true;
1655 }
1656}
1657
Douglas Gregor82e52372012-11-06 19:39:40 +00001658/// \brief Parse optional attributes.
1659///
1660/// attributes:
1661/// attribute attributes
1662/// attribute
1663///
1664/// attribute:
1665/// [ identifier ]
1666///
1667/// \param Attrs Will be filled in with the parsed attributes.
1668///
1669/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001670bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001671 bool HadError = false;
1672
1673 while (Tok.is(MMToken::LSquare)) {
1674 // Consume the '['.
1675 SourceLocation LSquareLoc = consumeToken();
1676
1677 // Check whether we have an attribute name here.
1678 if (!Tok.is(MMToken::Identifier)) {
1679 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1680 skipUntil(MMToken::RSquare);
1681 if (Tok.is(MMToken::RSquare))
1682 consumeToken();
1683 HadError = true;
1684 }
1685
1686 // Decode the attribute name.
1687 AttributeKind Attribute
1688 = llvm::StringSwitch<AttributeKind>(Tok.getString())
1689 .Case("system", AT_system)
1690 .Default(AT_unknown);
1691 switch (Attribute) {
1692 case AT_unknown:
1693 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1694 << Tok.getString();
1695 break;
1696
1697 case AT_system:
1698 Attrs.IsSystem = true;
1699 break;
1700 }
1701 consumeToken();
1702
1703 // Consume the ']'.
1704 if (!Tok.is(MMToken::RSquare)) {
1705 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1706 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1707 skipUntil(MMToken::RSquare);
1708 HadError = true;
1709 }
1710
1711 if (Tok.is(MMToken::RSquare))
1712 consumeToken();
1713 }
1714
1715 return HadError;
1716}
1717
Douglas Gregor6a1db482011-12-09 02:04:43 +00001718/// \brief If there is a specific header search directory due the presence
1719/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1720const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1721 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1722 // If we have an umbrella directory, use that.
1723 if (Mod->hasUmbrellaDir())
1724 return Mod->getUmbrellaDir();
1725
1726 // If we have a framework directory, stop looking.
1727 if (Mod->IsFramework)
1728 return 0;
1729 }
1730
1731 return 0;
1732}
1733
Douglas Gregora30cfe52011-11-11 19:10:28 +00001734/// \brief Parse a module map file.
1735///
1736/// module-map-file:
1737/// module-declaration*
1738bool ModuleMapParser::parseModuleMapFile() {
1739 do {
1740 switch (Tok.Kind) {
1741 case MMToken::EndOfFile:
1742 return HadError;
1743
Douglas Gregor587986e2011-12-07 02:23:45 +00001744 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001745 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001746 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001747 parseModuleDecl();
1748 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001749
Douglas Gregor51f564f2011-12-31 04:05:44 +00001750 case MMToken::Comma:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001751 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001752 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001753 case MMToken::HeaderKeyword:
1754 case MMToken::Identifier:
1755 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001756 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001757 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001758 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001759 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001760 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001761 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001762 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001763 case MMToken::StringLiteral:
1764 case MMToken::UmbrellaKeyword:
1765 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1766 HadError = true;
1767 consumeToken();
1768 break;
1769 }
1770 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001771}
1772
1773bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001774 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1775 = ParsedModuleMap.find(File);
1776 if (Known != ParsedModuleMap.end())
1777 return Known->second;
1778
Douglas Gregordc58aa72012-01-30 06:01:29 +00001779 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001780 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1781 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1782 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001783 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001784
1785 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001786 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1787 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001788 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001789 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001790 bool Result = Parser.parseModuleMapFile();
1791 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001792 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001793 return Result;
1794}