blob: 25e5bee9ce3a8b95db89c59527fb53f1deeccdf0 [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 Gregoraa60f9c2013-01-04 19:44:26 +0000166#ifdef LLVM_ON_UNIX
167 // 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.
171 char RealDirName[PATH_MAX];
172 StringRef DirName;
173 if (realpath(Dir->getName(), RealDirName))
174 DirName = RealDirName;
175 else
176 DirName = Dir->getName();
177#else
Douglas Gregoradb97992011-11-16 23:02:25 +0000178 StringRef DirName = Dir->getName();
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000179#endif
Douglas Gregore209e502011-12-06 01:10:29 +0000180
181 // Keep walking up the directory hierarchy, looking for a directory with
182 // an umbrella header.
183 do {
184 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
185 = UmbrellaDirs.find(Dir);
186 if (KnownDir != UmbrellaDirs.end()) {
187 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000188
189 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000190 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000191 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000192 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000193 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000194
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000195 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000196 // Infer submodules for each of the directories we found between
197 // the directory of the umbrella header and the directory where
198 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000199 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000200
Douglas Gregor6a1db482011-12-09 02:04:43 +0000201 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000202 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000203 SmallString<32> NameBuf;
204 StringRef Name = sanitizeFilenameAsIdentifier(
205 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
206 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000207 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000208 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000209
210 // Associate the module and the directory.
211 UmbrellaDirs[SkippedDirs[I-1]] = Result;
212
213 // If inferred submodules export everything they import, add a
214 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000215 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000216 Result->Exports.push_back(Module::ExportDecl(0, true));
217 }
218
219 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000220 SmallString<32> NameBuf;
221 StringRef Name = sanitizeFilenameAsIdentifier(
222 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000223 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000224 Explicit).first;
Argyrios Kyrtzidisc7782d92012-10-05 00:22:33 +0000225 Result->TopHeaders.insert(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000226
227 // If inferred submodules export everything they import, add a
228 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000229 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000230 Result->Exports.push_back(Module::ExportDecl(0, true));
231 } else {
232 // Record each of the directories we stepped through as being part of
233 // the module we found, since the umbrella header covers them all.
234 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
235 UmbrellaDirs[SkippedDirs[I]] = Result;
236 }
237
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000238 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000239
240 // If a header corresponds to an unavailable module, don't report
241 // that it maps to anything.
242 if (!Result->isAvailable())
243 return 0;
244
Douglas Gregore209e502011-12-06 01:10:29 +0000245 return Result;
246 }
247
248 SkippedDirs.push_back(Dir);
249
Douglas Gregoradb97992011-11-16 23:02:25 +0000250 // Retrieve our parent path.
251 DirName = llvm::sys::path::parent_path(DirName);
252 if (DirName.empty())
253 break;
254
255 // Resolve the parent path to a directory entry.
256 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000257 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000258
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000259 return 0;
260}
261
Douglas Gregor51f564f2011-12-31 04:05:44 +0000262bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000263 HeadersMap::iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000264 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000265 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000266
267 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000268 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000269 StringRef DirName = Dir->getName();
270
271 // Keep walking up the directory hierarchy, looking for a directory with
272 // an umbrella header.
273 do {
274 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
275 = UmbrellaDirs.find(Dir);
276 if (KnownDir != UmbrellaDirs.end()) {
277 Module *Found = KnownDir->second;
278 if (!Found->isAvailable())
279 return true;
280
281 // Search up the module stack until we find a module with an umbrella
282 // directory.
283 Module *UmbrellaModule = Found;
284 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
285 UmbrellaModule = UmbrellaModule->Parent;
286
287 if (UmbrellaModule->InferSubmodules) {
288 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
289 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000290 SmallString<32> NameBuf;
291 StringRef Name = sanitizeFilenameAsIdentifier(
292 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
293 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000294 Found = lookupModuleQualified(Name, Found);
295 if (!Found)
296 return false;
297 if (!Found->isAvailable())
298 return true;
299 }
300
301 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000302 SmallString<32> NameBuf;
303 StringRef Name = sanitizeFilenameAsIdentifier(
304 llvm::sys::path::stem(Header->getName()),
305 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000306 Found = lookupModuleQualified(Name, Found);
307 if (!Found)
308 return false;
309 }
310
311 return !Found->isAvailable();
312 }
313
314 SkippedDirs.push_back(Dir);
315
316 // Retrieve our parent path.
317 DirName = llvm::sys::path::parent_path(DirName);
318 if (DirName.empty())
319 break;
320
321 // Resolve the parent path to a directory entry.
322 Dir = SourceMgr->getFileManager().getDirectory(DirName);
323 } while (Dir);
324
325 return false;
326}
327
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000328Module *ModuleMap::findModule(StringRef Name) {
Douglas Gregor484535e2011-11-11 23:20:24 +0000329 llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
330 if (Known != Modules.end())
331 return Known->getValue();
332
333 return 0;
334}
335
Douglas Gregor90db2602011-12-02 01:47:07 +0000336Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
337 for(; Context; Context = Context->Parent) {
338 if (Module *Sub = lookupModuleQualified(Name, Context))
339 return Sub;
340 }
341
342 return findModule(Name);
343}
344
345Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
346 if (!Context)
347 return findModule(Name);
348
Douglas Gregorb7a78192012-01-04 23:32:19 +0000349 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000350}
351
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000352std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000353ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
354 bool IsExplicit) {
355 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000356 if (Module *Sub = lookupModuleQualified(Name, Parent))
357 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000358
359 // Create a new module with this name.
360 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
361 IsExplicit);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000362 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000363 Modules[Name] = Result;
364 return std::make_pair(Result, true);
365}
366
Douglas Gregor82e52372012-11-06 19:39:40 +0000367bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
368 StringRef Name, bool &IsSystem) {
369 // Check whether we have already looked into the parent directory
370 // for a module map.
371 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
372 inferred = InferredDirectories.find(ParentDir);
373 if (inferred == InferredDirectories.end())
374 return false;
375
376 if (!inferred->second.InferModules)
377 return false;
378
379 // We're allowed to infer for this directory, but make sure it's okay
380 // to infer this particular module.
381 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
382 inferred->second.ExcludedModules.end(),
383 Name) == inferred->second.ExcludedModules.end();
384
385 if (canInfer && inferred->second.InferSystemModules)
386 IsSystem = true;
387
388 return canInfer;
389}
390
Douglas Gregor8767dc22013-01-14 17:57:51 +0000391/// \brief For a framework module, infer the framework against which we
392/// should link.
393static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
394 FileManager &FileMgr) {
395 assert(Mod->IsFramework && "Can only infer linking for framework modules");
396 assert(!Mod->isSubFramework() &&
397 "Can only infer linking for top-level frameworks");
398
399 SmallString<128> LibName;
400 LibName += FrameworkDir->getName();
401 llvm::sys::path::append(LibName, Mod->Name);
402 if (FileMgr.getFile(LibName)) {
403 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
404 /*IsFramework=*/true));
405 }
406}
407
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000408Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000409ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000410 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000411 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000412 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000413 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000414 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
415 return Mod;
416
417 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000418
419 // If the framework has a parent path from which we're allowed to infer
420 // a framework module, do so.
421 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000422 // Determine whether we're allowed to infer a module map.
423 StringRef FrameworkDirName = FrameworkDir->getName();
424#ifdef LLVM_ON_UNIX
425 // Note: as an egregious but useful hack we use the real path here, because
426 // we might be looking at an embedded framework that symlinks out to a
427 // top-level framework, and we need to infer as if we were naming the
428 // top-level framework.
429 char RealFrameworkDirName[PATH_MAX];
430 if (realpath(FrameworkDir->getName(), RealFrameworkDirName))
431 FrameworkDirName = RealFrameworkDirName;
432#endif
433
Douglas Gregor82e52372012-11-06 19:39:40 +0000434 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000435 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000436 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000437 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000438 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
439 // Check whether we have already looked into the parent directory
440 // for a module map.
441 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
442 inferred = InferredDirectories.find(ParentDir);
443 if (inferred == InferredDirectories.end()) {
444 // We haven't looked here before. Load a module map, if there is
445 // one.
446 SmallString<128> ModMapPath = Parent;
447 llvm::sys::path::append(ModMapPath, "module.map");
448 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
449 parseModuleMapFile(ModMapFile);
450 inferred = InferredDirectories.find(ParentDir);
451 }
452
453 if (inferred == InferredDirectories.end())
454 inferred = InferredDirectories.insert(
455 std::make_pair(ParentDir, InferredDirectory())).first;
456 }
457
458 if (inferred->second.InferModules) {
459 // We're allowed to infer for this directory, but make sure it's okay
460 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000461 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000462 canInfer = std::find(inferred->second.ExcludedModules.begin(),
463 inferred->second.ExcludedModules.end(),
464 Name) == inferred->second.ExcludedModules.end();
465
466 if (inferred->second.InferSystemModules)
467 IsSystem = true;
468 }
469 }
470 }
471
472 // If we're not allowed to infer a framework module, don't.
473 if (!canInfer)
474 return 0;
475 }
476
477
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000478 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000479 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000480 llvm::sys::path::append(UmbrellaName, "Headers");
481 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000482 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000483
484 // FIXME: If there's no umbrella header, we could probably scan the
485 // framework to load *everything*. But, it's not clear that this is a good
486 // idea.
487 if (!UmbrellaHeader)
488 return 0;
489
Douglas Gregorac252a32011-12-06 19:39:29 +0000490 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
491 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000492 if (IsSystem)
493 Result->IsSystem = IsSystem;
494
Douglas Gregorb7a78192012-01-04 23:32:19 +0000495 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000496 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000497
Douglas Gregor489ad432011-12-08 18:00:48 +0000498 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000499 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000500 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000501 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000502
503 // export *
504 Result->Exports.push_back(Module::ExportDecl(0, true));
505
Douglas Gregore209e502011-12-06 01:10:29 +0000506 // module * { export * }
507 Result->InferSubmodules = true;
508 Result->InferExportWildcard = true;
509
Douglas Gregorac252a32011-12-06 19:39:29 +0000510 // Look for subframeworks.
511 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000512 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000513 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000514 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000515 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000516 llvm::sys::path::native(SubframeworksDirName.str(),
517 SubframeworksDirNameNative);
518 for (llvm::sys::fs::directory_iterator
519 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000520 Dir != DirEnd && !EC; Dir.increment(EC)) {
521 if (!StringRef(Dir->path()).endswith(".framework"))
522 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000523
Douglas Gregorac252a32011-12-06 19:39:29 +0000524 if (const DirectoryEntry *SubframeworkDir
525 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000526 // Note: as an egregious but useful hack, we use the real path here and
527 // check whether it is actually a subdirectory of the parent directory.
528 // This will not be the case if the 'subframework' is actually a symlink
529 // out to a top-level framework.
530#ifdef LLVM_ON_UNIX
531 char RealSubframeworkDirName[PATH_MAX];
532 if (realpath(Dir->path().c_str(), RealSubframeworkDirName)) {
533 StringRef SubframeworkDirName = RealSubframeworkDirName;
534
535 bool FoundParent = false;
536 do {
537 // Get the parent directory name.
538 SubframeworkDirName
539 = llvm::sys::path::parent_path(SubframeworkDirName);
540 if (SubframeworkDirName.empty())
541 break;
542
543 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
544 FoundParent = true;
545 break;
546 }
547 } while (true);
548
549 if (!FoundParent)
550 continue;
551 }
552#endif
553
Douglas Gregorac252a32011-12-06 19:39:29 +0000554 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000555 SmallString<32> NameBuf;
556 inferFrameworkModule(sanitizeFilenameAsIdentifier(
557 llvm::sys::path::stem(Dir->path()), NameBuf),
558 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000559 }
560 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000561
Douglas Gregor8767dc22013-01-14 17:57:51 +0000562 // If the module is a top-level framework, automatically link against the
563 // framework.
564 if (!Result->isSubFramework()) {
565 inferFrameworkLink(Result, FrameworkDir, FileMgr);
566 }
567
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000568 return Result;
569}
570
Douglas Gregore209e502011-12-06 01:10:29 +0000571void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000572 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000573 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000574 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000575}
576
Douglas Gregor77d029f2011-12-08 19:11:24 +0000577void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
578 Mod->Umbrella = UmbrellaDir;
579 UmbrellaDirs[UmbrellaDir] = Mod;
580}
581
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000582void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
583 bool Excluded) {
584 if (Excluded)
585 Mod->ExcludedHeaders.push_back(Header);
586 else
587 Mod->Headers.push_back(Header);
588 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000589}
590
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000591const FileEntry *
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000592ModuleMap::getContainingModuleMapFile(Module *Module) {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000593 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
594 return 0;
595
596 return SourceMgr->getFileEntryForID(
597 SourceMgr->getFileID(Module->DefinitionLoc));
598}
599
Douglas Gregora30cfe52011-11-11 19:10:28 +0000600void ModuleMap::dump() {
601 llvm::errs() << "Modules:";
602 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
603 MEnd = Modules.end();
604 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000605 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000606
607 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000608 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000609 H != HEnd; ++H) {
610 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000611 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000612 }
613}
614
Douglas Gregor90db2602011-12-02 01:47:07 +0000615bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
616 bool HadError = false;
617 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
618 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
619 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000620 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000621 Mod->Exports.push_back(Export);
622 else
623 HadError = true;
624 }
625 Mod->UnresolvedExports.clear();
626 return HadError;
627}
628
Douglas Gregor55988682011-12-05 16:33:54 +0000629Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
630 if (Loc.isInvalid())
631 return 0;
632
633 // Use the expansion location to determine which module we're in.
634 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
635 if (!ExpansionLoc.isFileID())
636 return 0;
637
638
639 const SourceManager &SrcMgr = Loc.getManager();
640 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000641
Douglas Gregor303aae92012-01-06 17:19:32 +0000642 while (const FileEntry *ExpansionFile
643 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
644 // Find the module that owns this header (if any).
645 if (Module *Mod = findModuleForHeader(ExpansionFile))
646 return Mod;
647
648 // No module owns this header, so look up the inclusion chain to see if
649 // any included header has an associated module.
650 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
651 if (IncludeLoc.isInvalid())
652 return 0;
653
654 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
655 }
656
657 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000658}
659
Douglas Gregora30cfe52011-11-11 19:10:28 +0000660//----------------------------------------------------------------------------//
661// Module map file parser
662//----------------------------------------------------------------------------//
663
664namespace clang {
665 /// \brief A token in a module map file.
666 struct MMToken {
667 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000668 Comma,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000669 EndOfFile,
670 HeaderKeyword,
671 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000672 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000673 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000674 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000675 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000676 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000677 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000678 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000679 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000680 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000681 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000682 StringLiteral,
683 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000684 RBrace,
685 LSquare,
686 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000687 } Kind;
688
689 unsigned Location;
690 unsigned StringLength;
691 const char *StringData;
692
693 void clear() {
694 Kind = EndOfFile;
695 Location = 0;
696 StringLength = 0;
697 StringData = 0;
698 }
699
700 bool is(TokenKind K) const { return Kind == K; }
701
702 SourceLocation getLocation() const {
703 return SourceLocation::getFromRawEncoding(Location);
704 }
705
706 StringRef getString() const {
707 return StringRef(StringData, StringLength);
708 }
709 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000710
711 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000712 struct Attributes {
713 Attributes() : IsSystem() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000714
715 /// \brief Whether this is a system module.
716 unsigned IsSystem : 1;
717 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000718
Douglas Gregor82e52372012-11-06 19:39:40 +0000719
Douglas Gregora30cfe52011-11-11 19:10:28 +0000720 class ModuleMapParser {
721 Lexer &L;
722 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000723
724 /// \brief Default target information, used only for string literal
725 /// parsing.
726 const TargetInfo *Target;
727
Douglas Gregora30cfe52011-11-11 19:10:28 +0000728 DiagnosticsEngine &Diags;
729 ModuleMap &Map;
730
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000731 /// \brief The directory that this module map resides in.
732 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000733
734 /// \brief The directory containing Clang-supplied headers.
735 const DirectoryEntry *BuiltinIncludeDir;
736
Douglas Gregora30cfe52011-11-11 19:10:28 +0000737 /// \brief Whether an error occurred.
738 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000739
Douglas Gregora30cfe52011-11-11 19:10:28 +0000740 /// \brief Stores string data for the various string literals referenced
741 /// during parsing.
742 llvm::BumpPtrAllocator StringData;
743
744 /// \brief The current token.
745 MMToken Tok;
746
747 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000748 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000749
750 /// \brief Consume the current token and return its location.
751 SourceLocation consumeToken();
752
753 /// \brief Skip tokens until we reach the a token with the given kind
754 /// (or the end of the file).
755 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000756
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000757 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000758 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000759 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000760 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000761 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000762 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000763 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000764 void parseLinkDecl();
Douglas Gregor82e52372012-11-06 19:39:40 +0000765 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000766 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000767
Douglas Gregor6a1db482011-12-09 02:04:43 +0000768 const DirectoryEntry *getOverriddenHeaderSearchDir();
769
Douglas Gregora30cfe52011-11-11 19:10:28 +0000770 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000771 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000772 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000773 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000774 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000775 const DirectoryEntry *Directory,
776 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000777 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000778 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
779 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000780 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000781 Tok.clear();
782 consumeToken();
783 }
784
785 bool parseModuleMapFile();
786 };
787}
788
789SourceLocation ModuleMapParser::consumeToken() {
790retry:
791 SourceLocation Result = Tok.getLocation();
792 Tok.clear();
793
794 Token LToken;
795 L.LexFromRawLexer(LToken);
796 Tok.Location = LToken.getLocation().getRawEncoding();
797 switch (LToken.getKind()) {
798 case tok::raw_identifier:
799 Tok.StringData = LToken.getRawIdentifierData();
800 Tok.StringLength = LToken.getLength();
801 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
802 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000803 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000804 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000805 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000806 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000807 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000808 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000809 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000810 .Case("umbrella", MMToken::UmbrellaKeyword)
811 .Default(MMToken::Identifier);
812 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000813
814 case tok::comma:
815 Tok.Kind = MMToken::Comma;
816 break;
817
Douglas Gregora30cfe52011-11-11 19:10:28 +0000818 case tok::eof:
819 Tok.Kind = MMToken::EndOfFile;
820 break;
821
822 case tok::l_brace:
823 Tok.Kind = MMToken::LBrace;
824 break;
825
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000826 case tok::l_square:
827 Tok.Kind = MMToken::LSquare;
828 break;
829
Douglas Gregor90db2602011-12-02 01:47:07 +0000830 case tok::period:
831 Tok.Kind = MMToken::Period;
832 break;
833
Douglas Gregora30cfe52011-11-11 19:10:28 +0000834 case tok::r_brace:
835 Tok.Kind = MMToken::RBrace;
836 break;
837
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000838 case tok::r_square:
839 Tok.Kind = MMToken::RSquare;
840 break;
841
Douglas Gregor90db2602011-12-02 01:47:07 +0000842 case tok::star:
843 Tok.Kind = MMToken::Star;
844 break;
845
Douglas Gregora30cfe52011-11-11 19:10:28 +0000846 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000847 if (LToken.hasUDSuffix()) {
848 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
849 HadError = true;
850 goto retry;
851 }
852
Douglas Gregora30cfe52011-11-11 19:10:28 +0000853 // Parse the string literal.
854 LangOptions LangOpts;
855 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
856 if (StringLiteral.hadError)
857 goto retry;
858
859 // Copy the string literal into our string data allocator.
860 unsigned Length = StringLiteral.GetStringLength();
861 char *Saved = StringData.Allocate<char>(Length + 1);
862 memcpy(Saved, StringLiteral.GetString().data(), Length);
863 Saved[Length] = 0;
864
865 // Form the token.
866 Tok.Kind = MMToken::StringLiteral;
867 Tok.StringData = Saved;
868 Tok.StringLength = Length;
869 break;
870 }
871
872 case tok::comment:
873 goto retry;
874
875 default:
876 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
877 HadError = true;
878 goto retry;
879 }
880
881 return Result;
882}
883
884void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
885 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000886 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000887 do {
888 switch (Tok.Kind) {
889 case MMToken::EndOfFile:
890 return;
891
892 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000893 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000894 return;
895
896 ++braceDepth;
897 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000898
899 case MMToken::LSquare:
900 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
901 return;
902
903 ++squareDepth;
904 break;
905
Douglas Gregora30cfe52011-11-11 19:10:28 +0000906 case MMToken::RBrace:
907 if (braceDepth > 0)
908 --braceDepth;
909 else if (Tok.is(K))
910 return;
911 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000912
913 case MMToken::RSquare:
914 if (squareDepth > 0)
915 --squareDepth;
916 else if (Tok.is(K))
917 return;
918 break;
919
Douglas Gregora30cfe52011-11-11 19:10:28 +0000920 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000921 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000922 return;
923 break;
924 }
925
926 consumeToken();
927 } while (true);
928}
929
Douglas Gregor587986e2011-12-07 02:23:45 +0000930/// \brief Parse a module-id.
931///
932/// module-id:
933/// identifier
934/// identifier '.' module-id
935///
936/// \returns true if an error occurred, false otherwise.
937bool ModuleMapParser::parseModuleId(ModuleId &Id) {
938 Id.clear();
939 do {
940 if (Tok.is(MMToken::Identifier)) {
941 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
942 consumeToken();
943 } else {
944 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
945 return true;
946 }
947
948 if (!Tok.is(MMToken::Period))
949 break;
950
951 consumeToken();
952 } while (true);
953
954 return false;
955}
956
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000957namespace {
958 /// \brief Enumerates the known attributes.
959 enum AttributeKind {
960 /// \brief An unknown attribute.
961 AT_unknown,
962 /// \brief The 'system' attribute.
963 AT_system
964 };
965}
966
Douglas Gregora30cfe52011-11-11 19:10:28 +0000967/// \brief Parse a module declaration.
968///
969/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000970/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
971/// { module-member* }
972///
Douglas Gregora30cfe52011-11-11 19:10:28 +0000973/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +0000974/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000975/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +0000976/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +0000977/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000978/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +0000979///
980/// submodule-declaration:
981/// module-declaration
982/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000983void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +0000984 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
985 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +0000986 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +0000987 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000988 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +0000989 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +0000990
Douglas Gregord620a842011-12-06 17:16:41 +0000991 // Parse 'explicit' keyword, if present.
992 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +0000993 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +0000994 Explicit = true;
995 }
996
997 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +0000998 if (Tok.is(MMToken::FrameworkKeyword)) {
999 consumeToken();
1000 Framework = true;
1001 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001002
1003 // Parse 'module' keyword.
1004 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001005 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001006 consumeToken();
1007 HadError = true;
1008 return;
1009 }
1010 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001011
1012 // If we have a wildcard for the module name, this is an inferred submodule.
1013 // Parse it.
1014 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001015 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001016
1017 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001018 ModuleId Id;
1019 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001020 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001021 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001022 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001023
Douglas Gregor587986e2011-12-07 02:23:45 +00001024 if (ActiveModule) {
1025 if (Id.size() > 1) {
1026 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1027 << SourceRange(Id.front().second, Id.back().second);
1028
1029 HadError = true;
1030 return;
1031 }
1032 } else if (Id.size() == 1 && Explicit) {
1033 // Top-level modules can't be explicit.
1034 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1035 Explicit = false;
1036 ExplicitLoc = SourceLocation();
1037 HadError = true;
1038 }
1039
1040 Module *PreviousActiveModule = ActiveModule;
1041 if (Id.size() > 1) {
1042 // This module map defines a submodule. Go find the module of which it
1043 // is a submodule.
1044 ActiveModule = 0;
1045 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1046 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1047 ActiveModule = Next;
1048 continue;
1049 }
1050
1051 if (ActiveModule) {
1052 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1053 << Id[I].first << ActiveModule->getTopLevelModule();
1054 } else {
1055 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1056 }
1057 HadError = true;
1058 return;
1059 }
1060 }
1061
1062 StringRef ModuleName = Id.back().first;
1063 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001064
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001065 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001066 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001067 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001068
Douglas Gregora30cfe52011-11-11 19:10:28 +00001069 // Parse the opening brace.
1070 if (!Tok.is(MMToken::LBrace)) {
1071 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1072 << ModuleName;
1073 HadError = true;
1074 return;
1075 }
1076 SourceLocation LBraceLoc = consumeToken();
1077
1078 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001079 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001080 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1081 // Skip the module definition.
1082 skipUntil(MMToken::RBrace);
1083 if (Tok.is(MMToken::RBrace))
1084 consumeToken();
1085 else {
1086 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1087 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1088 HadError = true;
1089 }
1090 return;
1091 }
1092
Douglas Gregora30cfe52011-11-11 19:10:28 +00001093 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1094 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001095 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001096
1097 // Skip the module definition.
1098 skipUntil(MMToken::RBrace);
1099 if (Tok.is(MMToken::RBrace))
1100 consumeToken();
1101
1102 HadError = true;
1103 return;
1104 }
1105
1106 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001107 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1108 Explicit).first;
1109 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001110 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001111 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001112
1113 bool Done = false;
1114 do {
1115 switch (Tok.Kind) {
1116 case MMToken::EndOfFile:
1117 case MMToken::RBrace:
1118 Done = true;
1119 break;
1120
1121 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001122 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001123 case MMToken::ModuleKeyword:
1124 parseModuleDecl();
1125 break;
1126
Douglas Gregor90db2602011-12-02 01:47:07 +00001127 case MMToken::ExportKeyword:
1128 parseExportDecl();
1129 break;
1130
Douglas Gregor51f564f2011-12-31 04:05:44 +00001131 case MMToken::RequiresKeyword:
1132 parseRequiresDecl();
1133 break;
1134
Douglas Gregor77d029f2011-12-08 19:11:24 +00001135 case MMToken::UmbrellaKeyword: {
1136 SourceLocation UmbrellaLoc = consumeToken();
1137 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001138 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001139 else
1140 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001141 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001142 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001143
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001144 case MMToken::ExcludeKeyword: {
1145 SourceLocation ExcludeLoc = consumeToken();
1146 if (Tok.is(MMToken::HeaderKeyword)) {
1147 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1148 } else {
1149 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1150 << "exclude";
1151 }
1152 break;
1153 }
1154
Douglas Gregor489ad432011-12-08 18:00:48 +00001155 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001156 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001157 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001158
1159 case MMToken::LinkKeyword:
1160 parseLinkDecl();
1161 break;
1162
Douglas Gregora30cfe52011-11-11 19:10:28 +00001163 default:
1164 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1165 consumeToken();
1166 break;
1167 }
1168 } while (!Done);
1169
1170 if (Tok.is(MMToken::RBrace))
1171 consumeToken();
1172 else {
1173 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1174 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1175 HadError = true;
1176 }
1177
Douglas Gregor8767dc22013-01-14 17:57:51 +00001178 // If the active module is a top-level framework, and there are no link
1179 // libraries, automatically link against the framework.
1180 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1181 ActiveModule->LinkLibraries.empty()) {
1182 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1183 }
1184
Douglas Gregor587986e2011-12-07 02:23:45 +00001185 // We're done parsing this module. Pop back to the previous module.
1186 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001187}
Douglas Gregord620a842011-12-06 17:16:41 +00001188
Douglas Gregor51f564f2011-12-31 04:05:44 +00001189/// \brief Parse a requires declaration.
1190///
1191/// requires-declaration:
1192/// 'requires' feature-list
1193///
1194/// feature-list:
1195/// identifier ',' feature-list
1196/// identifier
1197void ModuleMapParser::parseRequiresDecl() {
1198 assert(Tok.is(MMToken::RequiresKeyword));
1199
1200 // Parse 'requires' keyword.
1201 consumeToken();
1202
1203 // Parse the feature-list.
1204 do {
1205 if (!Tok.is(MMToken::Identifier)) {
1206 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1207 HadError = true;
1208 return;
1209 }
1210
1211 // Consume the feature name.
1212 std::string Feature = Tok.getString();
1213 consumeToken();
1214
1215 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001216 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001217
1218 if (!Tok.is(MMToken::Comma))
1219 break;
1220
1221 // Consume the comma.
1222 consumeToken();
1223 } while (true);
1224}
1225
Douglas Gregord620a842011-12-06 17:16:41 +00001226/// \brief Append to \p Paths the set of paths needed to get to the
1227/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001228static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001229 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001230 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001231 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001232 for (; Mod; Mod = Mod->Parent) {
1233 if (Mod->IsFramework)
1234 Paths.push_back(Mod->Name);
1235 }
1236
1237 if (Paths.empty())
1238 return;
1239
1240 // Add Frameworks/Name.framework for each subframework.
1241 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1242 llvm::sys::path::append(Path, "Frameworks");
1243 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1244 }
1245}
1246
Douglas Gregor2f04f182012-02-02 18:42:48 +00001247/// \brief Determine whether the given file name is the name of a builtin
1248/// header, supplied by Clang to replace, override, or augment existing system
1249/// headers.
1250static bool isBuiltinHeader(StringRef FileName) {
1251 return llvm::StringSwitch<bool>(FileName)
1252 .Case("float.h", true)
1253 .Case("iso646.h", true)
1254 .Case("limits.h", true)
1255 .Case("stdalign.h", true)
1256 .Case("stdarg.h", true)
1257 .Case("stdbool.h", true)
1258 .Case("stddef.h", true)
1259 .Case("stdint.h", true)
1260 .Case("tgmath.h", true)
1261 .Case("unwind.h", true)
1262 .Default(false);
1263}
1264
Douglas Gregora30cfe52011-11-11 19:10:28 +00001265/// \brief Parse a header declaration.
1266///
1267/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001268/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001269/// 'exclude'[opt] 'header' string-literal
1270void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1271 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001272 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001273 consumeToken();
1274
Douglas Gregor489ad432011-12-08 18:00:48 +00001275 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001276 bool Exclude = ExcludeLoc.isValid();
1277 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001278 // Parse the header name.
1279 if (!Tok.is(MMToken::StringLiteral)) {
1280 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1281 << "header";
1282 HadError = true;
1283 return;
1284 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001285 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001286 SourceLocation FileNameLoc = consumeToken();
1287
Douglas Gregor77d029f2011-12-08 19:11:24 +00001288 // Check whether we already have an umbrella.
1289 if (Umbrella && ActiveModule->Umbrella) {
1290 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1291 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001292 HadError = true;
1293 return;
1294 }
1295
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001296 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001297 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001298 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001299 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001300 if (llvm::sys::path::is_absolute(FileName)) {
1301 PathName = FileName;
1302 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001303 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1304 PathName = Dir->getName();
1305 llvm::sys::path::append(PathName, FileName);
1306 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001307 } else {
1308 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001309 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001310 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001311
Douglas Gregord620a842011-12-06 17:16:41 +00001312 if (ActiveModule->isPartOfFramework()) {
1313 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001314
1315 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001316 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001317 llvm::sys::path::append(PathName, FileName);
1318 File = SourceMgr.getFileManager().getFile(PathName);
1319
1320 if (!File) {
1321 // Check whether this file is in the private headers.
1322 PathName.resize(PathLength);
1323 llvm::sys::path::append(PathName, "PrivateHeaders");
1324 llvm::sys::path::append(PathName, FileName);
1325 File = SourceMgr.getFileManager().getFile(PathName);
1326 }
1327 } else {
1328 // Lookup for normal headers.
1329 llvm::sys::path::append(PathName, FileName);
1330 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001331
1332 // If this is a system module with a top-level header, this header
1333 // may have a counterpart (or replacement) in the set of headers
1334 // supplied by Clang. Find that builtin header.
1335 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1336 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001337 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001338 llvm::sys::path::append(BuiltinPathName, FileName);
1339 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1340
1341 // If Clang supplies this header but the underlying system does not,
1342 // just silently swap in our builtin version. Otherwise, we'll end
1343 // up adding both (later).
1344 if (!File && BuiltinFile) {
1345 File = BuiltinFile;
1346 BuiltinFile = 0;
1347 }
1348 }
Douglas Gregord620a842011-12-06 17:16:41 +00001349 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001350 }
Douglas Gregora8654052011-11-17 22:09:43 +00001351
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001352 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1353 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001354 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001355 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001356 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001357 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001358 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001359 } else if (Umbrella) {
1360 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001361 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001362 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001363 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001364 HadError = true;
1365 } else {
1366 // Record this umbrella header.
1367 Map.setUmbrellaHeader(ActiveModule, File);
1368 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001369 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001370 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001371 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001372
1373 // If there is a builtin counterpart to this file, add it now.
1374 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001375 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001376 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001377 } else if (!Exclude) {
1378 // Ignore excluded header files. They're optional anyway.
1379
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001380 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001381 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001382 HadError = true;
1383 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001384}
1385
Douglas Gregor77d029f2011-12-08 19:11:24 +00001386/// \brief Parse an umbrella directory declaration.
1387///
1388/// umbrella-dir-declaration:
1389/// umbrella string-literal
1390void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1391 // Parse the directory name.
1392 if (!Tok.is(MMToken::StringLiteral)) {
1393 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1394 << "umbrella";
1395 HadError = true;
1396 return;
1397 }
1398
1399 std::string DirName = Tok.getString();
1400 SourceLocation DirNameLoc = consumeToken();
1401
1402 // Check whether we already have an umbrella.
1403 if (ActiveModule->Umbrella) {
1404 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1405 << ActiveModule->getFullModuleName();
1406 HadError = true;
1407 return;
1408 }
1409
1410 // Look for this file.
1411 const DirectoryEntry *Dir = 0;
1412 if (llvm::sys::path::is_absolute(DirName))
1413 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1414 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001415 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001416 PathName = Directory->getName();
1417 llvm::sys::path::append(PathName, DirName);
1418 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1419 }
1420
1421 if (!Dir) {
1422 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1423 << DirName;
1424 HadError = true;
1425 return;
1426 }
1427
1428 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1429 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1430 << OwningModule->getFullModuleName();
1431 HadError = true;
1432 return;
1433 }
1434
1435 // Record this umbrella directory.
1436 Map.setUmbrellaDir(ActiveModule, Dir);
1437}
1438
Douglas Gregor90db2602011-12-02 01:47:07 +00001439/// \brief Parse a module export declaration.
1440///
1441/// export-declaration:
1442/// 'export' wildcard-module-id
1443///
1444/// wildcard-module-id:
1445/// identifier
1446/// '*'
1447/// identifier '.' wildcard-module-id
1448void ModuleMapParser::parseExportDecl() {
1449 assert(Tok.is(MMToken::ExportKeyword));
1450 SourceLocation ExportLoc = consumeToken();
1451
1452 // Parse the module-id with an optional wildcard at the end.
1453 ModuleId ParsedModuleId;
1454 bool Wildcard = false;
1455 do {
1456 if (Tok.is(MMToken::Identifier)) {
1457 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1458 Tok.getLocation()));
1459 consumeToken();
1460
1461 if (Tok.is(MMToken::Period)) {
1462 consumeToken();
1463 continue;
1464 }
1465
1466 break;
1467 }
1468
1469 if(Tok.is(MMToken::Star)) {
1470 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001471 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001472 break;
1473 }
1474
1475 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1476 HadError = true;
1477 return;
1478 } while (true);
1479
1480 Module::UnresolvedExportDecl Unresolved = {
1481 ExportLoc, ParsedModuleId, Wildcard
1482 };
1483 ActiveModule->UnresolvedExports.push_back(Unresolved);
1484}
1485
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001486/// \brief Parse a link declaration.
1487///
1488/// module-declaration:
1489/// 'link' 'framework'[opt] string-literal
1490void ModuleMapParser::parseLinkDecl() {
1491 assert(Tok.is(MMToken::LinkKeyword));
1492 SourceLocation LinkLoc = consumeToken();
1493
1494 // Parse the optional 'framework' keyword.
1495 bool IsFramework = false;
1496 if (Tok.is(MMToken::FrameworkKeyword)) {
1497 consumeToken();
1498 IsFramework = true;
1499 }
1500
1501 // Parse the library name
1502 if (!Tok.is(MMToken::StringLiteral)) {
1503 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1504 << IsFramework << SourceRange(LinkLoc);
1505 HadError = true;
1506 return;
1507 }
1508
1509 std::string LibraryName = Tok.getString();
1510 consumeToken();
1511 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1512 IsFramework));
1513}
1514
1515/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001516///
1517/// module-declaration:
1518/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1519/// { inferred-module-member* }
1520///
1521/// inferred-module-member:
1522/// 'export' '*'
1523/// 'exclude' identifier
1524void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001525 assert(Tok.is(MMToken::Star));
1526 SourceLocation StarLoc = consumeToken();
1527 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001528
Douglas Gregor1e123682011-12-05 22:27:44 +00001529 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001530 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001531 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1532 Failed = true;
1533 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001534
1535 if (ActiveModule) {
1536 // Inferred modules must have umbrella directories.
1537 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1538 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1539 Failed = true;
1540 }
1541
1542 // Check for redefinition of an inferred module.
1543 if (!Failed && ActiveModule->InferSubmodules) {
1544 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1545 if (ActiveModule->InferredSubmoduleLoc.isValid())
1546 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1547 diag::note_mmap_prev_definition);
1548 Failed = true;
1549 }
1550
1551 // Check for the 'framework' keyword, which is not permitted here.
1552 if (Framework) {
1553 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1554 Framework = false;
1555 }
1556 } else if (Explicit) {
1557 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1558 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001559 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001560
Douglas Gregor1e123682011-12-05 22:27:44 +00001561 // If there were any problems with this inferred submodule, skip its body.
1562 if (Failed) {
1563 if (Tok.is(MMToken::LBrace)) {
1564 consumeToken();
1565 skipUntil(MMToken::RBrace);
1566 if (Tok.is(MMToken::RBrace))
1567 consumeToken();
1568 }
1569 HadError = true;
1570 return;
1571 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001572
1573 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001574 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001575 parseOptionalAttributes(Attrs);
1576
1577 if (ActiveModule) {
1578 // Note that we have an inferred submodule.
1579 ActiveModule->InferSubmodules = true;
1580 ActiveModule->InferredSubmoduleLoc = StarLoc;
1581 ActiveModule->InferExplicitSubmodules = Explicit;
1582 } else {
1583 // We'll be inferring framework modules for this directory.
1584 Map.InferredDirectories[Directory].InferModules = true;
1585 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1586 }
1587
Douglas Gregor1e123682011-12-05 22:27:44 +00001588 // Parse the opening brace.
1589 if (!Tok.is(MMToken::LBrace)) {
1590 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1591 HadError = true;
1592 return;
1593 }
1594 SourceLocation LBraceLoc = consumeToken();
1595
1596 // Parse the body of the inferred submodule.
1597 bool Done = false;
1598 do {
1599 switch (Tok.Kind) {
1600 case MMToken::EndOfFile:
1601 case MMToken::RBrace:
1602 Done = true;
1603 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001604
1605 case MMToken::ExcludeKeyword: {
1606 if (ActiveModule) {
1607 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001608 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001609 consumeToken();
1610 break;
1611 }
1612
1613 consumeToken();
1614 if (!Tok.is(MMToken::Identifier)) {
1615 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1616 break;
1617 }
1618
1619 Map.InferredDirectories[Directory].ExcludedModules
1620 .push_back(Tok.getString());
1621 consumeToken();
1622 break;
1623 }
1624
1625 case MMToken::ExportKeyword:
1626 if (!ActiveModule) {
1627 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001628 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001629 consumeToken();
1630 break;
1631 }
1632
Douglas Gregor1e123682011-12-05 22:27:44 +00001633 consumeToken();
1634 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001635 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001636 else
1637 Diags.Report(Tok.getLocation(),
1638 diag::err_mmap_expected_export_wildcard);
1639 consumeToken();
1640 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001641
Douglas Gregor1e123682011-12-05 22:27:44 +00001642 case MMToken::ExplicitKeyword:
1643 case MMToken::ModuleKeyword:
1644 case MMToken::HeaderKeyword:
1645 case MMToken::UmbrellaKeyword:
1646 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001647 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001648 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001649 consumeToken();
1650 break;
1651 }
1652 } while (!Done);
1653
1654 if (Tok.is(MMToken::RBrace))
1655 consumeToken();
1656 else {
1657 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1658 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1659 HadError = true;
1660 }
1661}
1662
Douglas Gregor82e52372012-11-06 19:39:40 +00001663/// \brief Parse optional attributes.
1664///
1665/// attributes:
1666/// attribute attributes
1667/// attribute
1668///
1669/// attribute:
1670/// [ identifier ]
1671///
1672/// \param Attrs Will be filled in with the parsed attributes.
1673///
1674/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001675bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001676 bool HadError = false;
1677
1678 while (Tok.is(MMToken::LSquare)) {
1679 // Consume the '['.
1680 SourceLocation LSquareLoc = consumeToken();
1681
1682 // Check whether we have an attribute name here.
1683 if (!Tok.is(MMToken::Identifier)) {
1684 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1685 skipUntil(MMToken::RSquare);
1686 if (Tok.is(MMToken::RSquare))
1687 consumeToken();
1688 HadError = true;
1689 }
1690
1691 // Decode the attribute name.
1692 AttributeKind Attribute
1693 = llvm::StringSwitch<AttributeKind>(Tok.getString())
1694 .Case("system", AT_system)
1695 .Default(AT_unknown);
1696 switch (Attribute) {
1697 case AT_unknown:
1698 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1699 << Tok.getString();
1700 break;
1701
1702 case AT_system:
1703 Attrs.IsSystem = true;
1704 break;
1705 }
1706 consumeToken();
1707
1708 // Consume the ']'.
1709 if (!Tok.is(MMToken::RSquare)) {
1710 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1711 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1712 skipUntil(MMToken::RSquare);
1713 HadError = true;
1714 }
1715
1716 if (Tok.is(MMToken::RSquare))
1717 consumeToken();
1718 }
1719
1720 return HadError;
1721}
1722
Douglas Gregor6a1db482011-12-09 02:04:43 +00001723/// \brief If there is a specific header search directory due the presence
1724/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1725const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1726 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1727 // If we have an umbrella directory, use that.
1728 if (Mod->hasUmbrellaDir())
1729 return Mod->getUmbrellaDir();
1730
1731 // If we have a framework directory, stop looking.
1732 if (Mod->IsFramework)
1733 return 0;
1734 }
1735
1736 return 0;
1737}
1738
Douglas Gregora30cfe52011-11-11 19:10:28 +00001739/// \brief Parse a module map file.
1740///
1741/// module-map-file:
1742/// module-declaration*
1743bool ModuleMapParser::parseModuleMapFile() {
1744 do {
1745 switch (Tok.Kind) {
1746 case MMToken::EndOfFile:
1747 return HadError;
1748
Douglas Gregor587986e2011-12-07 02:23:45 +00001749 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001750 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001751 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001752 parseModuleDecl();
1753 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001754
Douglas Gregor51f564f2011-12-31 04:05:44 +00001755 case MMToken::Comma:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001756 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001757 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001758 case MMToken::HeaderKeyword:
1759 case MMToken::Identifier:
1760 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001761 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001762 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001763 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001764 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001765 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001766 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001767 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001768 case MMToken::StringLiteral:
1769 case MMToken::UmbrellaKeyword:
1770 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1771 HadError = true;
1772 consumeToken();
1773 break;
1774 }
1775 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001776}
1777
1778bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001779 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1780 = ParsedModuleMap.find(File);
1781 if (Known != ParsedModuleMap.end())
1782 return Known->second;
1783
Douglas Gregordc58aa72012-01-30 06:01:29 +00001784 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001785 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1786 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1787 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001788 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001789
1790 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001791 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1792 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001793 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001794 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001795 bool Result = Parser.parseModuleMapFile();
1796 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001797 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001798 return Result;
1799}