blob: 7ad42bef15de825bcb2fbb9e083319faf79ee8dc [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 Gregor3cc62772013-01-22 23:49:45 +000031#if defined(LLVM_ON_UNIX)
32#if defined(__linux__)
33#include <linux/limits.h>
34#endif
35#endif
Douglas Gregora30cfe52011-11-11 19:10:28 +000036using namespace clang;
37
Douglas Gregor90db2602011-12-02 01:47:07 +000038Module::ExportDecl
39ModuleMap::resolveExport(Module *Mod,
40 const Module::UnresolvedExportDecl &Unresolved,
41 bool Complain) {
Douglas Gregor0adaa882011-12-05 17:28:06 +000042 // We may have just a wildcard.
43 if (Unresolved.Id.empty()) {
44 assert(Unresolved.Wildcard && "Invalid unresolved export");
45 return Module::ExportDecl(0, true);
46 }
47
Douglas Gregor90db2602011-12-02 01:47:07 +000048 // Find the starting module.
49 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
50 if (!Context) {
51 if (Complain)
52 Diags->Report(Unresolved.Id[0].second,
53 diag::err_mmap_missing_module_unqualified)
54 << Unresolved.Id[0].first << Mod->getFullModuleName();
55
56 return Module::ExportDecl();
57 }
58
59 // Dig into the module path.
60 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
61 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
62 Context);
63 if (!Sub) {
64 if (Complain)
65 Diags->Report(Unresolved.Id[I].second,
66 diag::err_mmap_missing_module_qualified)
67 << Unresolved.Id[I].first << Context->getFullModuleName()
68 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
69
70 return Module::ExportDecl();
71 }
72
73 Context = Sub;
74 }
75
76 return Module::ExportDecl(Context, Unresolved.Wildcard);
77}
78
Douglas Gregor51f564f2011-12-31 04:05:44 +000079ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
Douglas Gregordc58aa72012-01-30 06:01:29 +000080 const LangOptions &LangOpts, const TargetInfo *Target)
Douglas Gregor2f04f182012-02-02 18:42:48 +000081 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000082{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000083 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
84 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000085 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora30cfe52011-11-11 19:10:28 +000086 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
87 SourceMgr = new SourceManager(*Diags, FileMgr);
88}
89
90ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +000091 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
92 IEnd = Modules.end();
93 I != IEnd; ++I) {
94 delete I->getValue();
95 }
96
Douglas Gregora30cfe52011-11-11 19:10:28 +000097 delete SourceMgr;
98}
99
Douglas Gregordc58aa72012-01-30 06:01:29 +0000100void ModuleMap::setTarget(const TargetInfo &Target) {
101 assert((!this->Target || this->Target == &Target) &&
102 "Improper target override");
103 this->Target = &Target;
104}
105
Douglas Gregor8b48e082012-10-12 21:15:50 +0000106/// \brief "Sanitize" a filename so that it can be used as an identifier.
107static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
108 SmallVectorImpl<char> &Buffer) {
109 if (Name.empty())
110 return Name;
111
112 // Check whether the filename is already an identifier; this is the common
113 // case.
114 bool isIdentifier = true;
115 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
116 if (isalpha(Name[I]) || Name[I] == '_' || (isdigit(Name[I]) && I > 0))
117 continue;
118
119 isIdentifier = false;
120 break;
121 }
122
123 if (!isIdentifier) {
124 // If we don't already have something with the form of an identifier,
125 // create a buffer with the sanitized name.
126 Buffer.clear();
127 if (isdigit(Name[0]))
128 Buffer.push_back('_');
129 Buffer.reserve(Buffer.size() + Name.size());
130 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
131 if (isalnum(Name[I]) || isspace(Name[I]))
132 Buffer.push_back(Name[I]);
133 else
134 Buffer.push_back('_');
135 }
136
137 Name = StringRef(Buffer.data(), Buffer.size());
138 }
139
140 while (llvm::StringSwitch<bool>(Name)
141#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
142#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
143#include "clang/Basic/TokenKinds.def"
144 .Default(false)) {
145 if (Name.data() != Buffer.data())
146 Buffer.append(Name.begin(), Name.end());
147 Buffer.push_back('_');
148 Name = StringRef(Buffer.data(), Buffer.size());
149 }
150
151 return Name;
152}
153
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000154Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000155 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000156 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000157 // If a header is not available, don't report that it maps to anything.
158 if (!Known->second.isAvailable())
Douglas Gregor51f564f2011-12-31 04:05:44 +0000159 return 0;
160
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000161 return Known->second.getModule();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000162 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000163
Douglas Gregoradb97992011-11-16 23:02:25 +0000164 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000165 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000166
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000167 // Note: as an egregious but useful hack we use the real path here, because
168 // frameworks moving from top-level frameworks to embedded frameworks tend
169 // to be symlinked from the top-level location to the embedded location,
170 // and we need to resolve lookups as if we had found the embedded location.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000171 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000172
173 // Keep walking up the directory hierarchy, looking for a directory with
174 // an umbrella header.
175 do {
176 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
177 = UmbrellaDirs.find(Dir);
178 if (KnownDir != UmbrellaDirs.end()) {
179 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000180
181 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000182 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000183 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000184 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000185 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000186
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000187 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000188 // Infer submodules for each of the directories we found between
189 // the directory of the umbrella header and the directory where
190 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000191 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000192
Douglas Gregor6a1db482011-12-09 02:04:43 +0000193 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000194 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000195 SmallString<32> NameBuf;
196 StringRef Name = sanitizeFilenameAsIdentifier(
197 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
198 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000199 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000200 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000201
202 // Associate the module and the directory.
203 UmbrellaDirs[SkippedDirs[I-1]] = Result;
204
205 // If inferred submodules export everything they import, add a
206 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000207 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000208 Result->Exports.push_back(Module::ExportDecl(0, true));
209 }
210
211 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000212 SmallString<32> NameBuf;
213 StringRef Name = sanitizeFilenameAsIdentifier(
214 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000215 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000216 Explicit).first;
Argyrios Kyrtzidisc7782d92012-10-05 00:22:33 +0000217 Result->TopHeaders.insert(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000218
219 // If inferred submodules export everything they import, add a
220 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000221 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000222 Result->Exports.push_back(Module::ExportDecl(0, true));
223 } else {
224 // Record each of the directories we stepped through as being part of
225 // the module we found, since the umbrella header covers them all.
226 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
227 UmbrellaDirs[SkippedDirs[I]] = Result;
228 }
229
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000230 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000231
232 // If a header corresponds to an unavailable module, don't report
233 // that it maps to anything.
234 if (!Result->isAvailable())
235 return 0;
236
Douglas Gregore209e502011-12-06 01:10:29 +0000237 return Result;
238 }
239
240 SkippedDirs.push_back(Dir);
241
Douglas Gregoradb97992011-11-16 23:02:25 +0000242 // Retrieve our parent path.
243 DirName = llvm::sys::path::parent_path(DirName);
244 if (DirName.empty())
245 break;
246
247 // Resolve the parent path to a directory entry.
248 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000249 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000250
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000251 return 0;
252}
253
Douglas Gregor51f564f2011-12-31 04:05:44 +0000254bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000255 HeadersMap::iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000256 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000257 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000258
259 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000260 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000261 StringRef DirName = Dir->getName();
262
263 // Keep walking up the directory hierarchy, looking for a directory with
264 // an umbrella header.
265 do {
266 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
267 = UmbrellaDirs.find(Dir);
268 if (KnownDir != UmbrellaDirs.end()) {
269 Module *Found = KnownDir->second;
270 if (!Found->isAvailable())
271 return true;
272
273 // Search up the module stack until we find a module with an umbrella
274 // directory.
275 Module *UmbrellaModule = Found;
276 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
277 UmbrellaModule = UmbrellaModule->Parent;
278
279 if (UmbrellaModule->InferSubmodules) {
280 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
281 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000282 SmallString<32> NameBuf;
283 StringRef Name = sanitizeFilenameAsIdentifier(
284 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
285 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000286 Found = lookupModuleQualified(Name, Found);
287 if (!Found)
288 return false;
289 if (!Found->isAvailable())
290 return true;
291 }
292
293 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000294 SmallString<32> NameBuf;
295 StringRef Name = sanitizeFilenameAsIdentifier(
296 llvm::sys::path::stem(Header->getName()),
297 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000298 Found = lookupModuleQualified(Name, Found);
299 if (!Found)
300 return false;
301 }
302
303 return !Found->isAvailable();
304 }
305
306 SkippedDirs.push_back(Dir);
307
308 // Retrieve our parent path.
309 DirName = llvm::sys::path::parent_path(DirName);
310 if (DirName.empty())
311 break;
312
313 // Resolve the parent path to a directory entry.
314 Dir = SourceMgr->getFileManager().getDirectory(DirName);
315 } while (Dir);
316
317 return false;
318}
319
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000320Module *ModuleMap::findModule(StringRef Name) {
Douglas Gregor484535e2011-11-11 23:20:24 +0000321 llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
322 if (Known != Modules.end())
323 return Known->getValue();
324
325 return 0;
326}
327
Douglas Gregor90db2602011-12-02 01:47:07 +0000328Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
329 for(; Context; Context = Context->Parent) {
330 if (Module *Sub = lookupModuleQualified(Name, Context))
331 return Sub;
332 }
333
334 return findModule(Name);
335}
336
337Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
338 if (!Context)
339 return findModule(Name);
340
Douglas Gregorb7a78192012-01-04 23:32:19 +0000341 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000342}
343
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000344std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000345ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
346 bool IsExplicit) {
347 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000348 if (Module *Sub = lookupModuleQualified(Name, Parent))
349 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000350
351 // Create a new module with this name.
352 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
353 IsExplicit);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000354 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000355 Modules[Name] = Result;
356 return std::make_pair(Result, true);
357}
358
Douglas Gregor82e52372012-11-06 19:39:40 +0000359bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
360 StringRef Name, bool &IsSystem) {
361 // Check whether we have already looked into the parent directory
362 // for a module map.
363 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
364 inferred = InferredDirectories.find(ParentDir);
365 if (inferred == InferredDirectories.end())
366 return false;
367
368 if (!inferred->second.InferModules)
369 return false;
370
371 // We're allowed to infer for this directory, but make sure it's okay
372 // to infer this particular module.
373 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
374 inferred->second.ExcludedModules.end(),
375 Name) == inferred->second.ExcludedModules.end();
376
377 if (canInfer && inferred->second.InferSystemModules)
378 IsSystem = true;
379
380 return canInfer;
381}
382
Douglas Gregor8767dc22013-01-14 17:57:51 +0000383/// \brief For a framework module, infer the framework against which we
384/// should link.
385static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
386 FileManager &FileMgr) {
387 assert(Mod->IsFramework && "Can only infer linking for framework modules");
388 assert(!Mod->isSubFramework() &&
389 "Can only infer linking for top-level frameworks");
390
391 SmallString<128> LibName;
392 LibName += FrameworkDir->getName();
393 llvm::sys::path::append(LibName, Mod->Name);
394 if (FileMgr.getFile(LibName)) {
395 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
396 /*IsFramework=*/true));
397 }
398}
399
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000400Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000401ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000402 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000403 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000404 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000405 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000406 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
407 return Mod;
408
409 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000410
411 // If the framework has a parent path from which we're allowed to infer
412 // a framework module, do so.
413 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000414 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000415
Douglas Gregor7005b902013-01-10 01:43:00 +0000416 // Note: as an egregious but useful hack we use the real path here, because
417 // we might be looking at an embedded framework that symlinks out to a
418 // top-level framework, and we need to infer as if we were naming the
419 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000420 StringRef FrameworkDirName
421 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000422
Douglas Gregor82e52372012-11-06 19:39:40 +0000423 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000424 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000425 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000426 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000427 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
428 // Check whether we have already looked into the parent directory
429 // for a module map.
430 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
431 inferred = InferredDirectories.find(ParentDir);
432 if (inferred == InferredDirectories.end()) {
433 // We haven't looked here before. Load a module map, if there is
434 // one.
435 SmallString<128> ModMapPath = Parent;
436 llvm::sys::path::append(ModMapPath, "module.map");
437 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
438 parseModuleMapFile(ModMapFile);
439 inferred = InferredDirectories.find(ParentDir);
440 }
441
442 if (inferred == InferredDirectories.end())
443 inferred = InferredDirectories.insert(
444 std::make_pair(ParentDir, InferredDirectory())).first;
445 }
446
447 if (inferred->second.InferModules) {
448 // We're allowed to infer for this directory, but make sure it's okay
449 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000450 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000451 canInfer = std::find(inferred->second.ExcludedModules.begin(),
452 inferred->second.ExcludedModules.end(),
453 Name) == inferred->second.ExcludedModules.end();
454
455 if (inferred->second.InferSystemModules)
456 IsSystem = true;
457 }
458 }
459 }
460
461 // If we're not allowed to infer a framework module, don't.
462 if (!canInfer)
463 return 0;
464 }
465
466
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000467 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000468 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000469 llvm::sys::path::append(UmbrellaName, "Headers");
470 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000471 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000472
473 // FIXME: If there's no umbrella header, we could probably scan the
474 // framework to load *everything*. But, it's not clear that this is a good
475 // idea.
476 if (!UmbrellaHeader)
477 return 0;
478
Douglas Gregorac252a32011-12-06 19:39:29 +0000479 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
480 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000481 if (IsSystem)
482 Result->IsSystem = IsSystem;
483
Douglas Gregorb7a78192012-01-04 23:32:19 +0000484 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000485 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000486
Douglas Gregor489ad432011-12-08 18:00:48 +0000487 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000488 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000489 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000490 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000491
492 // export *
493 Result->Exports.push_back(Module::ExportDecl(0, true));
494
Douglas Gregore209e502011-12-06 01:10:29 +0000495 // module * { export * }
496 Result->InferSubmodules = true;
497 Result->InferExportWildcard = true;
498
Douglas Gregorac252a32011-12-06 19:39:29 +0000499 // Look for subframeworks.
500 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000501 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000502 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000503 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000504 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000505 llvm::sys::path::native(SubframeworksDirName.str(),
506 SubframeworksDirNameNative);
507 for (llvm::sys::fs::directory_iterator
508 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000509 Dir != DirEnd && !EC; Dir.increment(EC)) {
510 if (!StringRef(Dir->path()).endswith(".framework"))
511 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000512
Douglas Gregorac252a32011-12-06 19:39:29 +0000513 if (const DirectoryEntry *SubframeworkDir
514 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000515 // Note: as an egregious but useful hack, we use the real path here and
516 // check whether it is actually a subdirectory of the parent directory.
517 // This will not be the case if the 'subframework' is actually a symlink
518 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000519 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
520 bool FoundParent = false;
521 do {
522 // Get the parent directory name.
523 SubframeworkDirName
524 = llvm::sys::path::parent_path(SubframeworkDirName);
525 if (SubframeworkDirName.empty())
526 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000527
Douglas Gregor713b7c02013-01-26 00:55:12 +0000528 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
529 FoundParent = true;
530 break;
531 }
532 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000533
Douglas Gregor713b7c02013-01-26 00:55:12 +0000534 if (!FoundParent)
535 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000536
Douglas Gregorac252a32011-12-06 19:39:29 +0000537 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000538 SmallString<32> NameBuf;
539 inferFrameworkModule(sanitizeFilenameAsIdentifier(
540 llvm::sys::path::stem(Dir->path()), NameBuf),
541 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000542 }
543 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000544
Douglas Gregor8767dc22013-01-14 17:57:51 +0000545 // If the module is a top-level framework, automatically link against the
546 // framework.
547 if (!Result->isSubFramework()) {
548 inferFrameworkLink(Result, FrameworkDir, FileMgr);
549 }
550
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000551 return Result;
552}
553
Douglas Gregore209e502011-12-06 01:10:29 +0000554void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000555 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000556 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000557 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000558}
559
Douglas Gregor77d029f2011-12-08 19:11:24 +0000560void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
561 Mod->Umbrella = UmbrellaDir;
562 UmbrellaDirs[UmbrellaDir] = Mod;
563}
564
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000565void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
566 bool Excluded) {
567 if (Excluded)
568 Mod->ExcludedHeaders.push_back(Header);
569 else
570 Mod->Headers.push_back(Header);
571 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000572}
573
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000574const FileEntry *
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000575ModuleMap::getContainingModuleMapFile(Module *Module) {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000576 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
577 return 0;
578
579 return SourceMgr->getFileEntryForID(
580 SourceMgr->getFileID(Module->DefinitionLoc));
581}
582
Douglas Gregora30cfe52011-11-11 19:10:28 +0000583void ModuleMap::dump() {
584 llvm::errs() << "Modules:";
585 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
586 MEnd = Modules.end();
587 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000588 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000589
590 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000591 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000592 H != HEnd; ++H) {
593 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000594 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000595 }
596}
597
Douglas Gregor90db2602011-12-02 01:47:07 +0000598bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
599 bool HadError = false;
600 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
601 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
602 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000603 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000604 Mod->Exports.push_back(Export);
605 else
606 HadError = true;
607 }
608 Mod->UnresolvedExports.clear();
609 return HadError;
610}
611
Douglas Gregor55988682011-12-05 16:33:54 +0000612Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
613 if (Loc.isInvalid())
614 return 0;
615
616 // Use the expansion location to determine which module we're in.
617 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
618 if (!ExpansionLoc.isFileID())
619 return 0;
620
621
622 const SourceManager &SrcMgr = Loc.getManager();
623 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000624
Douglas Gregor303aae92012-01-06 17:19:32 +0000625 while (const FileEntry *ExpansionFile
626 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
627 // Find the module that owns this header (if any).
628 if (Module *Mod = findModuleForHeader(ExpansionFile))
629 return Mod;
630
631 // No module owns this header, so look up the inclusion chain to see if
632 // any included header has an associated module.
633 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
634 if (IncludeLoc.isInvalid())
635 return 0;
636
637 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
638 }
639
640 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000641}
642
Douglas Gregora30cfe52011-11-11 19:10:28 +0000643//----------------------------------------------------------------------------//
644// Module map file parser
645//----------------------------------------------------------------------------//
646
647namespace clang {
648 /// \brief A token in a module map file.
649 struct MMToken {
650 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000651 Comma,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000652 EndOfFile,
653 HeaderKeyword,
654 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000655 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000656 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000657 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000658 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000659 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000660 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000661 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000662 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000663 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000664 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000665 StringLiteral,
666 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000667 RBrace,
668 LSquare,
669 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000670 } Kind;
671
672 unsigned Location;
673 unsigned StringLength;
674 const char *StringData;
675
676 void clear() {
677 Kind = EndOfFile;
678 Location = 0;
679 StringLength = 0;
680 StringData = 0;
681 }
682
683 bool is(TokenKind K) const { return Kind == K; }
684
685 SourceLocation getLocation() const {
686 return SourceLocation::getFromRawEncoding(Location);
687 }
688
689 StringRef getString() const {
690 return StringRef(StringData, StringLength);
691 }
692 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000693
694 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000695 struct Attributes {
696 Attributes() : IsSystem() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000697
698 /// \brief Whether this is a system module.
699 unsigned IsSystem : 1;
700 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000701
Douglas Gregor82e52372012-11-06 19:39:40 +0000702
Douglas Gregora30cfe52011-11-11 19:10:28 +0000703 class ModuleMapParser {
704 Lexer &L;
705 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000706
707 /// \brief Default target information, used only for string literal
708 /// parsing.
709 const TargetInfo *Target;
710
Douglas Gregora30cfe52011-11-11 19:10:28 +0000711 DiagnosticsEngine &Diags;
712 ModuleMap &Map;
713
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000714 /// \brief The directory that this module map resides in.
715 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000716
717 /// \brief The directory containing Clang-supplied headers.
718 const DirectoryEntry *BuiltinIncludeDir;
719
Douglas Gregora30cfe52011-11-11 19:10:28 +0000720 /// \brief Whether an error occurred.
721 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000722
Douglas Gregora30cfe52011-11-11 19:10:28 +0000723 /// \brief Stores string data for the various string literals referenced
724 /// during parsing.
725 llvm::BumpPtrAllocator StringData;
726
727 /// \brief The current token.
728 MMToken Tok;
729
730 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000731 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000732
733 /// \brief Consume the current token and return its location.
734 SourceLocation consumeToken();
735
736 /// \brief Skip tokens until we reach the a token with the given kind
737 /// (or the end of the file).
738 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000739
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000740 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000741 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000742 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000743 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000744 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000745 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000746 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000747 void parseLinkDecl();
Douglas Gregor82e52372012-11-06 19:39:40 +0000748 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000749 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000750
Douglas Gregor6a1db482011-12-09 02:04:43 +0000751 const DirectoryEntry *getOverriddenHeaderSearchDir();
752
Douglas Gregora30cfe52011-11-11 19:10:28 +0000753 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000754 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000755 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000756 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000757 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000758 const DirectoryEntry *Directory,
759 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000760 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000761 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
762 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000763 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000764 Tok.clear();
765 consumeToken();
766 }
767
768 bool parseModuleMapFile();
769 };
770}
771
772SourceLocation ModuleMapParser::consumeToken() {
773retry:
774 SourceLocation Result = Tok.getLocation();
775 Tok.clear();
776
777 Token LToken;
778 L.LexFromRawLexer(LToken);
779 Tok.Location = LToken.getLocation().getRawEncoding();
780 switch (LToken.getKind()) {
781 case tok::raw_identifier:
782 Tok.StringData = LToken.getRawIdentifierData();
783 Tok.StringLength = LToken.getLength();
784 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
785 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000786 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000787 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000788 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000789 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000790 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000791 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000792 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000793 .Case("umbrella", MMToken::UmbrellaKeyword)
794 .Default(MMToken::Identifier);
795 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000796
797 case tok::comma:
798 Tok.Kind = MMToken::Comma;
799 break;
800
Douglas Gregora30cfe52011-11-11 19:10:28 +0000801 case tok::eof:
802 Tok.Kind = MMToken::EndOfFile;
803 break;
804
805 case tok::l_brace:
806 Tok.Kind = MMToken::LBrace;
807 break;
808
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000809 case tok::l_square:
810 Tok.Kind = MMToken::LSquare;
811 break;
812
Douglas Gregor90db2602011-12-02 01:47:07 +0000813 case tok::period:
814 Tok.Kind = MMToken::Period;
815 break;
816
Douglas Gregora30cfe52011-11-11 19:10:28 +0000817 case tok::r_brace:
818 Tok.Kind = MMToken::RBrace;
819 break;
820
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000821 case tok::r_square:
822 Tok.Kind = MMToken::RSquare;
823 break;
824
Douglas Gregor90db2602011-12-02 01:47:07 +0000825 case tok::star:
826 Tok.Kind = MMToken::Star;
827 break;
828
Douglas Gregora30cfe52011-11-11 19:10:28 +0000829 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000830 if (LToken.hasUDSuffix()) {
831 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
832 HadError = true;
833 goto retry;
834 }
835
Douglas Gregora30cfe52011-11-11 19:10:28 +0000836 // Parse the string literal.
837 LangOptions LangOpts;
838 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
839 if (StringLiteral.hadError)
840 goto retry;
841
842 // Copy the string literal into our string data allocator.
843 unsigned Length = StringLiteral.GetStringLength();
844 char *Saved = StringData.Allocate<char>(Length + 1);
845 memcpy(Saved, StringLiteral.GetString().data(), Length);
846 Saved[Length] = 0;
847
848 // Form the token.
849 Tok.Kind = MMToken::StringLiteral;
850 Tok.StringData = Saved;
851 Tok.StringLength = Length;
852 break;
853 }
854
855 case tok::comment:
856 goto retry;
857
858 default:
859 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
860 HadError = true;
861 goto retry;
862 }
863
864 return Result;
865}
866
867void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
868 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000869 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000870 do {
871 switch (Tok.Kind) {
872 case MMToken::EndOfFile:
873 return;
874
875 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000876 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000877 return;
878
879 ++braceDepth;
880 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000881
882 case MMToken::LSquare:
883 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
884 return;
885
886 ++squareDepth;
887 break;
888
Douglas Gregora30cfe52011-11-11 19:10:28 +0000889 case MMToken::RBrace:
890 if (braceDepth > 0)
891 --braceDepth;
892 else if (Tok.is(K))
893 return;
894 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000895
896 case MMToken::RSquare:
897 if (squareDepth > 0)
898 --squareDepth;
899 else if (Tok.is(K))
900 return;
901 break;
902
Douglas Gregora30cfe52011-11-11 19:10:28 +0000903 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000904 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000905 return;
906 break;
907 }
908
909 consumeToken();
910 } while (true);
911}
912
Douglas Gregor587986e2011-12-07 02:23:45 +0000913/// \brief Parse a module-id.
914///
915/// module-id:
916/// identifier
917/// identifier '.' module-id
918///
919/// \returns true if an error occurred, false otherwise.
920bool ModuleMapParser::parseModuleId(ModuleId &Id) {
921 Id.clear();
922 do {
923 if (Tok.is(MMToken::Identifier)) {
924 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
925 consumeToken();
926 } else {
927 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
928 return true;
929 }
930
931 if (!Tok.is(MMToken::Period))
932 break;
933
934 consumeToken();
935 } while (true);
936
937 return false;
938}
939
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000940namespace {
941 /// \brief Enumerates the known attributes.
942 enum AttributeKind {
943 /// \brief An unknown attribute.
944 AT_unknown,
945 /// \brief The 'system' attribute.
946 AT_system
947 };
948}
949
Douglas Gregora30cfe52011-11-11 19:10:28 +0000950/// \brief Parse a module declaration.
951///
952/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000953/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
954/// { module-member* }
955///
Douglas Gregora30cfe52011-11-11 19:10:28 +0000956/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +0000957/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000958/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +0000959/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +0000960/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000961/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +0000962///
963/// submodule-declaration:
964/// module-declaration
965/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000966void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +0000967 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
968 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +0000969 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +0000970 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000971 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +0000972 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +0000973
Douglas Gregord620a842011-12-06 17:16:41 +0000974 // Parse 'explicit' keyword, if present.
975 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +0000976 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +0000977 Explicit = true;
978 }
979
980 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +0000981 if (Tok.is(MMToken::FrameworkKeyword)) {
982 consumeToken();
983 Framework = true;
984 }
Douglas Gregora30cfe52011-11-11 19:10:28 +0000985
986 // Parse 'module' keyword.
987 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +0000988 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000989 consumeToken();
990 HadError = true;
991 return;
992 }
993 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +0000994
995 // If we have a wildcard for the module name, this is an inferred submodule.
996 // Parse it.
997 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +0000998 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000999
1000 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001001 ModuleId Id;
1002 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001003 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001004 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001005 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001006
Douglas Gregor587986e2011-12-07 02:23:45 +00001007 if (ActiveModule) {
1008 if (Id.size() > 1) {
1009 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1010 << SourceRange(Id.front().second, Id.back().second);
1011
1012 HadError = true;
1013 return;
1014 }
1015 } else if (Id.size() == 1 && Explicit) {
1016 // Top-level modules can't be explicit.
1017 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1018 Explicit = false;
1019 ExplicitLoc = SourceLocation();
1020 HadError = true;
1021 }
1022
1023 Module *PreviousActiveModule = ActiveModule;
1024 if (Id.size() > 1) {
1025 // This module map defines a submodule. Go find the module of which it
1026 // is a submodule.
1027 ActiveModule = 0;
1028 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1029 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1030 ActiveModule = Next;
1031 continue;
1032 }
1033
1034 if (ActiveModule) {
1035 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1036 << Id[I].first << ActiveModule->getTopLevelModule();
1037 } else {
1038 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1039 }
1040 HadError = true;
1041 return;
1042 }
1043 }
1044
1045 StringRef ModuleName = Id.back().first;
1046 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001047
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001048 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001049 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001050 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001051
Douglas Gregora30cfe52011-11-11 19:10:28 +00001052 // Parse the opening brace.
1053 if (!Tok.is(MMToken::LBrace)) {
1054 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1055 << ModuleName;
1056 HadError = true;
1057 return;
1058 }
1059 SourceLocation LBraceLoc = consumeToken();
1060
1061 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001062 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001063 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1064 // Skip the module definition.
1065 skipUntil(MMToken::RBrace);
1066 if (Tok.is(MMToken::RBrace))
1067 consumeToken();
1068 else {
1069 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1070 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1071 HadError = true;
1072 }
1073 return;
1074 }
1075
Douglas Gregora30cfe52011-11-11 19:10:28 +00001076 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1077 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001078 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001079
1080 // Skip the module definition.
1081 skipUntil(MMToken::RBrace);
1082 if (Tok.is(MMToken::RBrace))
1083 consumeToken();
1084
1085 HadError = true;
1086 return;
1087 }
1088
1089 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001090 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1091 Explicit).first;
1092 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001093 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001094 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001095
1096 bool Done = false;
1097 do {
1098 switch (Tok.Kind) {
1099 case MMToken::EndOfFile:
1100 case MMToken::RBrace:
1101 Done = true;
1102 break;
1103
1104 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001105 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001106 case MMToken::ModuleKeyword:
1107 parseModuleDecl();
1108 break;
1109
Douglas Gregor90db2602011-12-02 01:47:07 +00001110 case MMToken::ExportKeyword:
1111 parseExportDecl();
1112 break;
1113
Douglas Gregor51f564f2011-12-31 04:05:44 +00001114 case MMToken::RequiresKeyword:
1115 parseRequiresDecl();
1116 break;
1117
Douglas Gregor77d029f2011-12-08 19:11:24 +00001118 case MMToken::UmbrellaKeyword: {
1119 SourceLocation UmbrellaLoc = consumeToken();
1120 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001121 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001122 else
1123 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001124 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001125 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001126
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001127 case MMToken::ExcludeKeyword: {
1128 SourceLocation ExcludeLoc = consumeToken();
1129 if (Tok.is(MMToken::HeaderKeyword)) {
1130 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1131 } else {
1132 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1133 << "exclude";
1134 }
1135 break;
1136 }
1137
Douglas Gregor489ad432011-12-08 18:00:48 +00001138 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001139 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001140 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001141
1142 case MMToken::LinkKeyword:
1143 parseLinkDecl();
1144 break;
1145
Douglas Gregora30cfe52011-11-11 19:10:28 +00001146 default:
1147 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1148 consumeToken();
1149 break;
1150 }
1151 } while (!Done);
1152
1153 if (Tok.is(MMToken::RBrace))
1154 consumeToken();
1155 else {
1156 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1157 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1158 HadError = true;
1159 }
1160
Douglas Gregor8767dc22013-01-14 17:57:51 +00001161 // If the active module is a top-level framework, and there are no link
1162 // libraries, automatically link against the framework.
1163 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1164 ActiveModule->LinkLibraries.empty()) {
1165 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1166 }
1167
Douglas Gregor587986e2011-12-07 02:23:45 +00001168 // We're done parsing this module. Pop back to the previous module.
1169 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001170}
Douglas Gregord620a842011-12-06 17:16:41 +00001171
Douglas Gregor51f564f2011-12-31 04:05:44 +00001172/// \brief Parse a requires declaration.
1173///
1174/// requires-declaration:
1175/// 'requires' feature-list
1176///
1177/// feature-list:
1178/// identifier ',' feature-list
1179/// identifier
1180void ModuleMapParser::parseRequiresDecl() {
1181 assert(Tok.is(MMToken::RequiresKeyword));
1182
1183 // Parse 'requires' keyword.
1184 consumeToken();
1185
1186 // Parse the feature-list.
1187 do {
1188 if (!Tok.is(MMToken::Identifier)) {
1189 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1190 HadError = true;
1191 return;
1192 }
1193
1194 // Consume the feature name.
1195 std::string Feature = Tok.getString();
1196 consumeToken();
1197
1198 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001199 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001200
1201 if (!Tok.is(MMToken::Comma))
1202 break;
1203
1204 // Consume the comma.
1205 consumeToken();
1206 } while (true);
1207}
1208
Douglas Gregord620a842011-12-06 17:16:41 +00001209/// \brief Append to \p Paths the set of paths needed to get to the
1210/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001211static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001212 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001213 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001214 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001215 for (; Mod; Mod = Mod->Parent) {
1216 if (Mod->IsFramework)
1217 Paths.push_back(Mod->Name);
1218 }
1219
1220 if (Paths.empty())
1221 return;
1222
1223 // Add Frameworks/Name.framework for each subframework.
1224 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1225 llvm::sys::path::append(Path, "Frameworks");
1226 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1227 }
1228}
1229
Douglas Gregor2f04f182012-02-02 18:42:48 +00001230/// \brief Determine whether the given file name is the name of a builtin
1231/// header, supplied by Clang to replace, override, or augment existing system
1232/// headers.
1233static bool isBuiltinHeader(StringRef FileName) {
1234 return llvm::StringSwitch<bool>(FileName)
1235 .Case("float.h", true)
1236 .Case("iso646.h", true)
1237 .Case("limits.h", true)
1238 .Case("stdalign.h", true)
1239 .Case("stdarg.h", true)
1240 .Case("stdbool.h", true)
1241 .Case("stddef.h", true)
1242 .Case("stdint.h", true)
1243 .Case("tgmath.h", true)
1244 .Case("unwind.h", true)
1245 .Default(false);
1246}
1247
Douglas Gregora30cfe52011-11-11 19:10:28 +00001248/// \brief Parse a header declaration.
1249///
1250/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001251/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001252/// 'exclude'[opt] 'header' string-literal
1253void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1254 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001255 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001256 consumeToken();
1257
Douglas Gregor489ad432011-12-08 18:00:48 +00001258 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001259 bool Exclude = ExcludeLoc.isValid();
1260 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001261 // Parse the header name.
1262 if (!Tok.is(MMToken::StringLiteral)) {
1263 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1264 << "header";
1265 HadError = true;
1266 return;
1267 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001268 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001269 SourceLocation FileNameLoc = consumeToken();
1270
Douglas Gregor77d029f2011-12-08 19:11:24 +00001271 // Check whether we already have an umbrella.
1272 if (Umbrella && ActiveModule->Umbrella) {
1273 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1274 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001275 HadError = true;
1276 return;
1277 }
1278
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001279 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001280 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001281 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001282 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001283 if (llvm::sys::path::is_absolute(FileName)) {
1284 PathName = FileName;
1285 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001286 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1287 PathName = Dir->getName();
1288 llvm::sys::path::append(PathName, FileName);
1289 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001290 } else {
1291 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001292 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001293 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001294
Douglas Gregord620a842011-12-06 17:16:41 +00001295 if (ActiveModule->isPartOfFramework()) {
1296 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001297
1298 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001299 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001300 llvm::sys::path::append(PathName, FileName);
1301 File = SourceMgr.getFileManager().getFile(PathName);
1302
1303 if (!File) {
1304 // Check whether this file is in the private headers.
1305 PathName.resize(PathLength);
1306 llvm::sys::path::append(PathName, "PrivateHeaders");
1307 llvm::sys::path::append(PathName, FileName);
1308 File = SourceMgr.getFileManager().getFile(PathName);
1309 }
1310 } else {
1311 // Lookup for normal headers.
1312 llvm::sys::path::append(PathName, FileName);
1313 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001314
1315 // If this is a system module with a top-level header, this header
1316 // may have a counterpart (or replacement) in the set of headers
1317 // supplied by Clang. Find that builtin header.
1318 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1319 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001320 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001321 llvm::sys::path::append(BuiltinPathName, FileName);
1322 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1323
1324 // If Clang supplies this header but the underlying system does not,
1325 // just silently swap in our builtin version. Otherwise, we'll end
1326 // up adding both (later).
1327 if (!File && BuiltinFile) {
1328 File = BuiltinFile;
1329 BuiltinFile = 0;
1330 }
1331 }
Douglas Gregord620a842011-12-06 17:16:41 +00001332 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001333 }
Douglas Gregora8654052011-11-17 22:09:43 +00001334
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001335 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1336 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001337 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001338 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001339 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001340 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001341 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001342 } else if (Umbrella) {
1343 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001344 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001345 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001346 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001347 HadError = true;
1348 } else {
1349 // Record this umbrella header.
1350 Map.setUmbrellaHeader(ActiveModule, File);
1351 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001352 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001353 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001354 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001355
1356 // If there is a builtin counterpart to this file, add it now.
1357 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001358 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001359 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001360 } else if (!Exclude) {
1361 // Ignore excluded header files. They're optional anyway.
1362
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001363 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001364 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001365 HadError = true;
1366 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001367}
1368
Douglas Gregor77d029f2011-12-08 19:11:24 +00001369/// \brief Parse an umbrella directory declaration.
1370///
1371/// umbrella-dir-declaration:
1372/// umbrella string-literal
1373void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1374 // Parse the directory name.
1375 if (!Tok.is(MMToken::StringLiteral)) {
1376 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1377 << "umbrella";
1378 HadError = true;
1379 return;
1380 }
1381
1382 std::string DirName = Tok.getString();
1383 SourceLocation DirNameLoc = consumeToken();
1384
1385 // Check whether we already have an umbrella.
1386 if (ActiveModule->Umbrella) {
1387 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1388 << ActiveModule->getFullModuleName();
1389 HadError = true;
1390 return;
1391 }
1392
1393 // Look for this file.
1394 const DirectoryEntry *Dir = 0;
1395 if (llvm::sys::path::is_absolute(DirName))
1396 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1397 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001398 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001399 PathName = Directory->getName();
1400 llvm::sys::path::append(PathName, DirName);
1401 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1402 }
1403
1404 if (!Dir) {
1405 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1406 << DirName;
1407 HadError = true;
1408 return;
1409 }
1410
1411 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1412 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1413 << OwningModule->getFullModuleName();
1414 HadError = true;
1415 return;
1416 }
1417
1418 // Record this umbrella directory.
1419 Map.setUmbrellaDir(ActiveModule, Dir);
1420}
1421
Douglas Gregor90db2602011-12-02 01:47:07 +00001422/// \brief Parse a module export declaration.
1423///
1424/// export-declaration:
1425/// 'export' wildcard-module-id
1426///
1427/// wildcard-module-id:
1428/// identifier
1429/// '*'
1430/// identifier '.' wildcard-module-id
1431void ModuleMapParser::parseExportDecl() {
1432 assert(Tok.is(MMToken::ExportKeyword));
1433 SourceLocation ExportLoc = consumeToken();
1434
1435 // Parse the module-id with an optional wildcard at the end.
1436 ModuleId ParsedModuleId;
1437 bool Wildcard = false;
1438 do {
1439 if (Tok.is(MMToken::Identifier)) {
1440 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1441 Tok.getLocation()));
1442 consumeToken();
1443
1444 if (Tok.is(MMToken::Period)) {
1445 consumeToken();
1446 continue;
1447 }
1448
1449 break;
1450 }
1451
1452 if(Tok.is(MMToken::Star)) {
1453 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001454 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001455 break;
1456 }
1457
1458 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1459 HadError = true;
1460 return;
1461 } while (true);
1462
1463 Module::UnresolvedExportDecl Unresolved = {
1464 ExportLoc, ParsedModuleId, Wildcard
1465 };
1466 ActiveModule->UnresolvedExports.push_back(Unresolved);
1467}
1468
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001469/// \brief Parse a link declaration.
1470///
1471/// module-declaration:
1472/// 'link' 'framework'[opt] string-literal
1473void ModuleMapParser::parseLinkDecl() {
1474 assert(Tok.is(MMToken::LinkKeyword));
1475 SourceLocation LinkLoc = consumeToken();
1476
1477 // Parse the optional 'framework' keyword.
1478 bool IsFramework = false;
1479 if (Tok.is(MMToken::FrameworkKeyword)) {
1480 consumeToken();
1481 IsFramework = true;
1482 }
1483
1484 // Parse the library name
1485 if (!Tok.is(MMToken::StringLiteral)) {
1486 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1487 << IsFramework << SourceRange(LinkLoc);
1488 HadError = true;
1489 return;
1490 }
1491
1492 std::string LibraryName = Tok.getString();
1493 consumeToken();
1494 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1495 IsFramework));
1496}
1497
1498/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001499///
1500/// module-declaration:
1501/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1502/// { inferred-module-member* }
1503///
1504/// inferred-module-member:
1505/// 'export' '*'
1506/// 'exclude' identifier
1507void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001508 assert(Tok.is(MMToken::Star));
1509 SourceLocation StarLoc = consumeToken();
1510 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001511
Douglas Gregor1e123682011-12-05 22:27:44 +00001512 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001513 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001514 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1515 Failed = true;
1516 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001517
1518 if (ActiveModule) {
1519 // Inferred modules must have umbrella directories.
1520 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1521 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1522 Failed = true;
1523 }
1524
1525 // Check for redefinition of an inferred module.
1526 if (!Failed && ActiveModule->InferSubmodules) {
1527 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1528 if (ActiveModule->InferredSubmoduleLoc.isValid())
1529 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1530 diag::note_mmap_prev_definition);
1531 Failed = true;
1532 }
1533
1534 // Check for the 'framework' keyword, which is not permitted here.
1535 if (Framework) {
1536 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1537 Framework = false;
1538 }
1539 } else if (Explicit) {
1540 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1541 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001542 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001543
Douglas Gregor1e123682011-12-05 22:27:44 +00001544 // If there were any problems with this inferred submodule, skip its body.
1545 if (Failed) {
1546 if (Tok.is(MMToken::LBrace)) {
1547 consumeToken();
1548 skipUntil(MMToken::RBrace);
1549 if (Tok.is(MMToken::RBrace))
1550 consumeToken();
1551 }
1552 HadError = true;
1553 return;
1554 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001555
1556 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001557 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001558 parseOptionalAttributes(Attrs);
1559
1560 if (ActiveModule) {
1561 // Note that we have an inferred submodule.
1562 ActiveModule->InferSubmodules = true;
1563 ActiveModule->InferredSubmoduleLoc = StarLoc;
1564 ActiveModule->InferExplicitSubmodules = Explicit;
1565 } else {
1566 // We'll be inferring framework modules for this directory.
1567 Map.InferredDirectories[Directory].InferModules = true;
1568 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1569 }
1570
Douglas Gregor1e123682011-12-05 22:27:44 +00001571 // Parse the opening brace.
1572 if (!Tok.is(MMToken::LBrace)) {
1573 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1574 HadError = true;
1575 return;
1576 }
1577 SourceLocation LBraceLoc = consumeToken();
1578
1579 // Parse the body of the inferred submodule.
1580 bool Done = false;
1581 do {
1582 switch (Tok.Kind) {
1583 case MMToken::EndOfFile:
1584 case MMToken::RBrace:
1585 Done = true;
1586 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001587
1588 case MMToken::ExcludeKeyword: {
1589 if (ActiveModule) {
1590 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001591 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001592 consumeToken();
1593 break;
1594 }
1595
1596 consumeToken();
1597 if (!Tok.is(MMToken::Identifier)) {
1598 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1599 break;
1600 }
1601
1602 Map.InferredDirectories[Directory].ExcludedModules
1603 .push_back(Tok.getString());
1604 consumeToken();
1605 break;
1606 }
1607
1608 case MMToken::ExportKeyword:
1609 if (!ActiveModule) {
1610 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001611 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001612 consumeToken();
1613 break;
1614 }
1615
Douglas Gregor1e123682011-12-05 22:27:44 +00001616 consumeToken();
1617 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001618 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001619 else
1620 Diags.Report(Tok.getLocation(),
1621 diag::err_mmap_expected_export_wildcard);
1622 consumeToken();
1623 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001624
Douglas Gregor1e123682011-12-05 22:27:44 +00001625 case MMToken::ExplicitKeyword:
1626 case MMToken::ModuleKeyword:
1627 case MMToken::HeaderKeyword:
1628 case MMToken::UmbrellaKeyword:
1629 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001630 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001631 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001632 consumeToken();
1633 break;
1634 }
1635 } while (!Done);
1636
1637 if (Tok.is(MMToken::RBrace))
1638 consumeToken();
1639 else {
1640 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1641 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1642 HadError = true;
1643 }
1644}
1645
Douglas Gregor82e52372012-11-06 19:39:40 +00001646/// \brief Parse optional attributes.
1647///
1648/// attributes:
1649/// attribute attributes
1650/// attribute
1651///
1652/// attribute:
1653/// [ identifier ]
1654///
1655/// \param Attrs Will be filled in with the parsed attributes.
1656///
1657/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001658bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001659 bool HadError = false;
1660
1661 while (Tok.is(MMToken::LSquare)) {
1662 // Consume the '['.
1663 SourceLocation LSquareLoc = consumeToken();
1664
1665 // Check whether we have an attribute name here.
1666 if (!Tok.is(MMToken::Identifier)) {
1667 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1668 skipUntil(MMToken::RSquare);
1669 if (Tok.is(MMToken::RSquare))
1670 consumeToken();
1671 HadError = true;
1672 }
1673
1674 // Decode the attribute name.
1675 AttributeKind Attribute
1676 = llvm::StringSwitch<AttributeKind>(Tok.getString())
1677 .Case("system", AT_system)
1678 .Default(AT_unknown);
1679 switch (Attribute) {
1680 case AT_unknown:
1681 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1682 << Tok.getString();
1683 break;
1684
1685 case AT_system:
1686 Attrs.IsSystem = true;
1687 break;
1688 }
1689 consumeToken();
1690
1691 // Consume the ']'.
1692 if (!Tok.is(MMToken::RSquare)) {
1693 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1694 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1695 skipUntil(MMToken::RSquare);
1696 HadError = true;
1697 }
1698
1699 if (Tok.is(MMToken::RSquare))
1700 consumeToken();
1701 }
1702
1703 return HadError;
1704}
1705
Douglas Gregor6a1db482011-12-09 02:04:43 +00001706/// \brief If there is a specific header search directory due the presence
1707/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1708const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1709 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1710 // If we have an umbrella directory, use that.
1711 if (Mod->hasUmbrellaDir())
1712 return Mod->getUmbrellaDir();
1713
1714 // If we have a framework directory, stop looking.
1715 if (Mod->IsFramework)
1716 return 0;
1717 }
1718
1719 return 0;
1720}
1721
Douglas Gregora30cfe52011-11-11 19:10:28 +00001722/// \brief Parse a module map file.
1723///
1724/// module-map-file:
1725/// module-declaration*
1726bool ModuleMapParser::parseModuleMapFile() {
1727 do {
1728 switch (Tok.Kind) {
1729 case MMToken::EndOfFile:
1730 return HadError;
1731
Douglas Gregor587986e2011-12-07 02:23:45 +00001732 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001733 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001734 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001735 parseModuleDecl();
1736 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001737
Douglas Gregor51f564f2011-12-31 04:05:44 +00001738 case MMToken::Comma:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001739 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001740 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001741 case MMToken::HeaderKeyword:
1742 case MMToken::Identifier:
1743 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001744 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001745 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001746 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001747 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001748 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001749 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001750 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001751 case MMToken::StringLiteral:
1752 case MMToken::UmbrellaKeyword:
1753 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1754 HadError = true;
1755 consumeToken();
1756 break;
1757 }
1758 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001759}
1760
1761bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001762 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1763 = ParsedModuleMap.find(File);
1764 if (Known != ParsedModuleMap.end())
1765 return Known->second;
1766
Douglas Gregordc58aa72012-01-30 06:01:29 +00001767 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001768 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1769 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1770 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001771 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001772
1773 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001774 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1775 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001776 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001777 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001778 bool Result = Parser.parseModuleMapFile();
1779 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001780 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001781 return Result;
1782}