blob: 1ceed54a0a7c410b00819ba6b1da1839a3b9cf0f [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"
Jordan Rose3f6f51e2013-02-08 22:30:41 +000015#include "clang/Basic/CharInfo.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000016#include "clang/Basic/Diagnostic.h"
Douglas Gregor02c23eb2012-10-23 22:26:28 +000017#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000018#include "clang/Basic/FileManager.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Basic/TargetOptions.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000021#include "clang/Lex/LexDiagnostic.h"
22#include "clang/Lex/Lexer.h"
23#include "clang/Lex/LiteralSupport.h"
24#include "llvm/ADT/StringRef.h"
25#include "llvm/ADT/StringSwitch.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000026#include "llvm/Support/Allocator.h"
Douglas Gregorac252a32011-12-06 19:39:29 +000027#include "llvm/Support/FileSystem.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000028#include "llvm/Support/Host.h"
Douglas Gregor8b6d3de2011-11-11 21:55:48 +000029#include "llvm/Support/PathV2.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000030#include "llvm/Support/raw_ostream.h"
Douglas Gregor98cfcbf2012-09-27 14:50:15 +000031#include <stdlib.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000032#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoadeb7822013-01-26 16:29:36 +000033#include <limits.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000034#endif
Douglas Gregora30cfe52011-11-11 19:10:28 +000035using namespace clang;
36
Douglas Gregor90db2602011-12-02 01:47:07 +000037Module::ExportDecl
38ModuleMap::resolveExport(Module *Mod,
39 const Module::UnresolvedExportDecl &Unresolved,
40 bool Complain) {
Douglas Gregor0adaa882011-12-05 17:28:06 +000041 // We may have just a wildcard.
42 if (Unresolved.Id.empty()) {
43 assert(Unresolved.Wildcard && "Invalid unresolved export");
44 return Module::ExportDecl(0, true);
45 }
46
Douglas Gregor90db2602011-12-02 01:47:07 +000047 // Find the starting module.
48 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
49 if (!Context) {
50 if (Complain)
51 Diags->Report(Unresolved.Id[0].second,
52 diag::err_mmap_missing_module_unqualified)
53 << Unresolved.Id[0].first << Mod->getFullModuleName();
54
55 return Module::ExportDecl();
56 }
57
58 // Dig into the module path.
59 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
60 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
61 Context);
62 if (!Sub) {
63 if (Complain)
64 Diags->Report(Unresolved.Id[I].second,
65 diag::err_mmap_missing_module_qualified)
66 << Unresolved.Id[I].first << Context->getFullModuleName()
67 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
68
69 return Module::ExportDecl();
70 }
71
72 Context = Sub;
73 }
74
75 return Module::ExportDecl(Context, Unresolved.Wildcard);
76}
77
Douglas Gregor51f564f2011-12-31 04:05:44 +000078ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
Douglas Gregordc58aa72012-01-30 06:01:29 +000079 const LangOptions &LangOpts, const TargetInfo *Target)
Douglas Gregor2f04f182012-02-02 18:42:48 +000080 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000081{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000082 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
83 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000084 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora30cfe52011-11-11 19:10:28 +000085 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
86 SourceMgr = new SourceManager(*Diags, FileMgr);
87}
88
89ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +000090 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
91 IEnd = Modules.end();
92 I != IEnd; ++I) {
93 delete I->getValue();
94 }
95
Douglas Gregora30cfe52011-11-11 19:10:28 +000096 delete SourceMgr;
97}
98
Douglas Gregordc58aa72012-01-30 06:01:29 +000099void ModuleMap::setTarget(const TargetInfo &Target) {
100 assert((!this->Target || this->Target == &Target) &&
101 "Improper target override");
102 this->Target = &Target;
103}
104
Douglas Gregor8b48e082012-10-12 21:15:50 +0000105/// \brief "Sanitize" a filename so that it can be used as an identifier.
106static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
107 SmallVectorImpl<char> &Buffer) {
108 if (Name.empty())
109 return Name;
110
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000111 if (!isValidIdentifier(Name)) {
Douglas Gregor8b48e082012-10-12 21:15:50 +0000112 // If we don't already have something with the form of an identifier,
113 // create a buffer with the sanitized name.
114 Buffer.clear();
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000115 if (isDigit(Name[0]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000116 Buffer.push_back('_');
117 Buffer.reserve(Buffer.size() + Name.size());
118 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000119 if (isIdentifierBody(Name[I]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000120 Buffer.push_back(Name[I]);
121 else
122 Buffer.push_back('_');
123 }
124
125 Name = StringRef(Buffer.data(), Buffer.size());
126 }
127
128 while (llvm::StringSwitch<bool>(Name)
129#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
130#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
131#include "clang/Basic/TokenKinds.def"
132 .Default(false)) {
133 if (Name.data() != Buffer.data())
134 Buffer.append(Name.begin(), Name.end());
135 Buffer.push_back('_');
136 Name = StringRef(Buffer.data(), Buffer.size());
137 }
138
139 return Name;
140}
141
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000142Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000143 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000144 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000145 // If a header is not available, don't report that it maps to anything.
146 if (!Known->second.isAvailable())
Douglas Gregor51f564f2011-12-31 04:05:44 +0000147 return 0;
148
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000149 return Known->second.getModule();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000150 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000151
Douglas Gregoradb97992011-11-16 23:02:25 +0000152 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000153 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000154
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000155 // Note: as an egregious but useful hack we use the real path here, because
156 // frameworks moving from top-level frameworks to embedded frameworks tend
157 // to be symlinked from the top-level location to the embedded location,
158 // and we need to resolve lookups as if we had found the embedded location.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000159 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000160
161 // Keep walking up the directory hierarchy, looking for a directory with
162 // an umbrella header.
163 do {
164 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
165 = UmbrellaDirs.find(Dir);
166 if (KnownDir != UmbrellaDirs.end()) {
167 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000168
169 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000170 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000171 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000172 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000173 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000174
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000175 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000176 // Infer submodules for each of the directories we found between
177 // the directory of the umbrella header and the directory where
178 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000179 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000180
Douglas Gregor6a1db482011-12-09 02:04:43 +0000181 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000182 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000183 SmallString<32> NameBuf;
184 StringRef Name = sanitizeFilenameAsIdentifier(
185 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
186 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000187 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000188 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000189
190 // Associate the module and the directory.
191 UmbrellaDirs[SkippedDirs[I-1]] = Result;
192
193 // If inferred submodules export everything they import, add a
194 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000195 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000196 Result->Exports.push_back(Module::ExportDecl(0, true));
197 }
198
199 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000200 SmallString<32> NameBuf;
201 StringRef Name = sanitizeFilenameAsIdentifier(
202 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000203 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000204 Explicit).first;
Argyrios Kyrtzidisc7782d92012-10-05 00:22:33 +0000205 Result->TopHeaders.insert(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000206
207 // If inferred submodules export everything they import, add a
208 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000209 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000210 Result->Exports.push_back(Module::ExportDecl(0, true));
211 } else {
212 // Record each of the directories we stepped through as being part of
213 // the module we found, since the umbrella header covers them all.
214 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
215 UmbrellaDirs[SkippedDirs[I]] = Result;
216 }
217
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000218 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000219
220 // If a header corresponds to an unavailable module, don't report
221 // that it maps to anything.
222 if (!Result->isAvailable())
223 return 0;
224
Douglas Gregore209e502011-12-06 01:10:29 +0000225 return Result;
226 }
227
228 SkippedDirs.push_back(Dir);
229
Douglas Gregoradb97992011-11-16 23:02:25 +0000230 // Retrieve our parent path.
231 DirName = llvm::sys::path::parent_path(DirName);
232 if (DirName.empty())
233 break;
234
235 // Resolve the parent path to a directory entry.
236 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000237 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000238
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000239 return 0;
240}
241
Douglas Gregor51f564f2011-12-31 04:05:44 +0000242bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000243 HeadersMap::iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000244 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000245 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000246
247 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000248 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000249 StringRef DirName = Dir->getName();
250
251 // Keep walking up the directory hierarchy, looking for a directory with
252 // an umbrella header.
253 do {
254 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
255 = UmbrellaDirs.find(Dir);
256 if (KnownDir != UmbrellaDirs.end()) {
257 Module *Found = KnownDir->second;
258 if (!Found->isAvailable())
259 return true;
260
261 // Search up the module stack until we find a module with an umbrella
262 // directory.
263 Module *UmbrellaModule = Found;
264 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
265 UmbrellaModule = UmbrellaModule->Parent;
266
267 if (UmbrellaModule->InferSubmodules) {
268 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
269 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000270 SmallString<32> NameBuf;
271 StringRef Name = sanitizeFilenameAsIdentifier(
272 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
273 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000274 Found = lookupModuleQualified(Name, Found);
275 if (!Found)
276 return false;
277 if (!Found->isAvailable())
278 return true;
279 }
280
281 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000282 SmallString<32> NameBuf;
283 StringRef Name = sanitizeFilenameAsIdentifier(
284 llvm::sys::path::stem(Header->getName()),
285 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000286 Found = lookupModuleQualified(Name, Found);
287 if (!Found)
288 return false;
289 }
290
291 return !Found->isAvailable();
292 }
293
294 SkippedDirs.push_back(Dir);
295
296 // Retrieve our parent path.
297 DirName = llvm::sys::path::parent_path(DirName);
298 if (DirName.empty())
299 break;
300
301 // Resolve the parent path to a directory entry.
302 Dir = SourceMgr->getFileManager().getDirectory(DirName);
303 } while (Dir);
304
305 return false;
306}
307
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000308Module *ModuleMap::findModule(StringRef Name) {
Douglas Gregor484535e2011-11-11 23:20:24 +0000309 llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
310 if (Known != Modules.end())
311 return Known->getValue();
312
313 return 0;
314}
315
Douglas Gregor90db2602011-12-02 01:47:07 +0000316Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
317 for(; Context; Context = Context->Parent) {
318 if (Module *Sub = lookupModuleQualified(Name, Context))
319 return Sub;
320 }
321
322 return findModule(Name);
323}
324
325Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
326 if (!Context)
327 return findModule(Name);
328
Douglas Gregorb7a78192012-01-04 23:32:19 +0000329 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000330}
331
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000332std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000333ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
334 bool IsExplicit) {
335 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000336 if (Module *Sub = lookupModuleQualified(Name, Parent))
337 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000338
339 // Create a new module with this name.
340 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
341 IsExplicit);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000342 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000343 Modules[Name] = Result;
344 return std::make_pair(Result, true);
345}
346
Douglas Gregor82e52372012-11-06 19:39:40 +0000347bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
348 StringRef Name, bool &IsSystem) {
349 // Check whether we have already looked into the parent directory
350 // for a module map.
351 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
352 inferred = InferredDirectories.find(ParentDir);
353 if (inferred == InferredDirectories.end())
354 return false;
355
356 if (!inferred->second.InferModules)
357 return false;
358
359 // We're allowed to infer for this directory, but make sure it's okay
360 // to infer this particular module.
361 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
362 inferred->second.ExcludedModules.end(),
363 Name) == inferred->second.ExcludedModules.end();
364
365 if (canInfer && inferred->second.InferSystemModules)
366 IsSystem = true;
367
368 return canInfer;
369}
370
Douglas Gregor8767dc22013-01-14 17:57:51 +0000371/// \brief For a framework module, infer the framework against which we
372/// should link.
373static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
374 FileManager &FileMgr) {
375 assert(Mod->IsFramework && "Can only infer linking for framework modules");
376 assert(!Mod->isSubFramework() &&
377 "Can only infer linking for top-level frameworks");
378
379 SmallString<128> LibName;
380 LibName += FrameworkDir->getName();
381 llvm::sys::path::append(LibName, Mod->Name);
382 if (FileMgr.getFile(LibName)) {
383 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
384 /*IsFramework=*/true));
385 }
386}
387
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000388Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000389ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000390 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000391 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000392 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000393 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000394 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
395 return Mod;
396
397 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000398
399 // If the framework has a parent path from which we're allowed to infer
400 // a framework module, do so.
401 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000402 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000403
Douglas Gregor7005b902013-01-10 01:43:00 +0000404 // Note: as an egregious but useful hack we use the real path here, because
405 // we might be looking at an embedded framework that symlinks out to a
406 // top-level framework, and we need to infer as if we were naming the
407 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000408 StringRef FrameworkDirName
409 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000410
Douglas Gregor82e52372012-11-06 19:39:40 +0000411 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000412 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000413 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000414 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000415 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
416 // Check whether we have already looked into the parent directory
417 // for a module map.
418 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
419 inferred = InferredDirectories.find(ParentDir);
420 if (inferred == InferredDirectories.end()) {
421 // We haven't looked here before. Load a module map, if there is
422 // one.
423 SmallString<128> ModMapPath = Parent;
424 llvm::sys::path::append(ModMapPath, "module.map");
425 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
426 parseModuleMapFile(ModMapFile);
427 inferred = InferredDirectories.find(ParentDir);
428 }
429
430 if (inferred == InferredDirectories.end())
431 inferred = InferredDirectories.insert(
432 std::make_pair(ParentDir, InferredDirectory())).first;
433 }
434
435 if (inferred->second.InferModules) {
436 // We're allowed to infer for this directory, but make sure it's okay
437 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000438 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000439 canInfer = std::find(inferred->second.ExcludedModules.begin(),
440 inferred->second.ExcludedModules.end(),
441 Name) == inferred->second.ExcludedModules.end();
442
443 if (inferred->second.InferSystemModules)
444 IsSystem = true;
445 }
446 }
447 }
448
449 // If we're not allowed to infer a framework module, don't.
450 if (!canInfer)
451 return 0;
452 }
453
454
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000455 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000456 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000457 llvm::sys::path::append(UmbrellaName, "Headers");
458 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000459 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000460
461 // FIXME: If there's no umbrella header, we could probably scan the
462 // framework to load *everything*. But, it's not clear that this is a good
463 // idea.
464 if (!UmbrellaHeader)
465 return 0;
466
Douglas Gregorac252a32011-12-06 19:39:29 +0000467 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
468 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000469 if (IsSystem)
470 Result->IsSystem = IsSystem;
471
Douglas Gregorb7a78192012-01-04 23:32:19 +0000472 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000473 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000474
Douglas Gregor489ad432011-12-08 18:00:48 +0000475 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000476 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000477 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000478 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000479
480 // export *
481 Result->Exports.push_back(Module::ExportDecl(0, true));
482
Douglas Gregore209e502011-12-06 01:10:29 +0000483 // module * { export * }
484 Result->InferSubmodules = true;
485 Result->InferExportWildcard = true;
486
Douglas Gregorac252a32011-12-06 19:39:29 +0000487 // Look for subframeworks.
488 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000489 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000490 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000491 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000492 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000493 llvm::sys::path::native(SubframeworksDirName.str(),
494 SubframeworksDirNameNative);
495 for (llvm::sys::fs::directory_iterator
496 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000497 Dir != DirEnd && !EC; Dir.increment(EC)) {
498 if (!StringRef(Dir->path()).endswith(".framework"))
499 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000500
Douglas Gregorac252a32011-12-06 19:39:29 +0000501 if (const DirectoryEntry *SubframeworkDir
502 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000503 // Note: as an egregious but useful hack, we use the real path here and
504 // check whether it is actually a subdirectory of the parent directory.
505 // This will not be the case if the 'subframework' is actually a symlink
506 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000507 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
508 bool FoundParent = false;
509 do {
510 // Get the parent directory name.
511 SubframeworkDirName
512 = llvm::sys::path::parent_path(SubframeworkDirName);
513 if (SubframeworkDirName.empty())
514 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000515
Douglas Gregor713b7c02013-01-26 00:55:12 +0000516 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
517 FoundParent = true;
518 break;
519 }
520 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000521
Douglas Gregor713b7c02013-01-26 00:55:12 +0000522 if (!FoundParent)
523 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000524
Douglas Gregorac252a32011-12-06 19:39:29 +0000525 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000526 SmallString<32> NameBuf;
527 inferFrameworkModule(sanitizeFilenameAsIdentifier(
528 llvm::sys::path::stem(Dir->path()), NameBuf),
529 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000530 }
531 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000532
Douglas Gregor8767dc22013-01-14 17:57:51 +0000533 // If the module is a top-level framework, automatically link against the
534 // framework.
535 if (!Result->isSubFramework()) {
536 inferFrameworkLink(Result, FrameworkDir, FileMgr);
537 }
538
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000539 return Result;
540}
541
Douglas Gregore209e502011-12-06 01:10:29 +0000542void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000543 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000544 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000545 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000546}
547
Douglas Gregor77d029f2011-12-08 19:11:24 +0000548void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
549 Mod->Umbrella = UmbrellaDir;
550 UmbrellaDirs[UmbrellaDir] = Mod;
551}
552
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000553void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
554 bool Excluded) {
555 if (Excluded)
556 Mod->ExcludedHeaders.push_back(Header);
557 else
558 Mod->Headers.push_back(Header);
559 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000560}
561
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000562const FileEntry *
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000563ModuleMap::getContainingModuleMapFile(Module *Module) {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000564 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
565 return 0;
566
567 return SourceMgr->getFileEntryForID(
568 SourceMgr->getFileID(Module->DefinitionLoc));
569}
570
Douglas Gregora30cfe52011-11-11 19:10:28 +0000571void ModuleMap::dump() {
572 llvm::errs() << "Modules:";
573 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
574 MEnd = Modules.end();
575 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000576 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000577
578 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000579 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000580 H != HEnd; ++H) {
581 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000582 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000583 }
584}
585
Douglas Gregor90db2602011-12-02 01:47:07 +0000586bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
587 bool HadError = false;
588 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
589 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
590 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000591 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000592 Mod->Exports.push_back(Export);
593 else
594 HadError = true;
595 }
596 Mod->UnresolvedExports.clear();
597 return HadError;
598}
599
Douglas Gregor55988682011-12-05 16:33:54 +0000600Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
601 if (Loc.isInvalid())
602 return 0;
603
604 // Use the expansion location to determine which module we're in.
605 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
606 if (!ExpansionLoc.isFileID())
607 return 0;
608
609
610 const SourceManager &SrcMgr = Loc.getManager();
611 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000612
Douglas Gregor303aae92012-01-06 17:19:32 +0000613 while (const FileEntry *ExpansionFile
614 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
615 // Find the module that owns this header (if any).
616 if (Module *Mod = findModuleForHeader(ExpansionFile))
617 return Mod;
618
619 // No module owns this header, so look up the inclusion chain to see if
620 // any included header has an associated module.
621 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
622 if (IncludeLoc.isInvalid())
623 return 0;
624
625 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
626 }
627
628 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000629}
630
Douglas Gregora30cfe52011-11-11 19:10:28 +0000631//----------------------------------------------------------------------------//
632// Module map file parser
633//----------------------------------------------------------------------------//
634
635namespace clang {
636 /// \brief A token in a module map file.
637 struct MMToken {
638 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000639 Comma,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000640 EndOfFile,
641 HeaderKeyword,
642 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000643 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000644 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000645 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000646 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000647 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000648 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000649 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000650 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000651 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000652 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000653 StringLiteral,
654 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000655 RBrace,
656 LSquare,
657 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000658 } Kind;
659
660 unsigned Location;
661 unsigned StringLength;
662 const char *StringData;
663
664 void clear() {
665 Kind = EndOfFile;
666 Location = 0;
667 StringLength = 0;
668 StringData = 0;
669 }
670
671 bool is(TokenKind K) const { return Kind == K; }
672
673 SourceLocation getLocation() const {
674 return SourceLocation::getFromRawEncoding(Location);
675 }
676
677 StringRef getString() const {
678 return StringRef(StringData, StringLength);
679 }
680 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000681
682 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000683 struct Attributes {
684 Attributes() : IsSystem() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000685
686 /// \brief Whether this is a system module.
687 unsigned IsSystem : 1;
688 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000689
Douglas Gregor82e52372012-11-06 19:39:40 +0000690
Douglas Gregora30cfe52011-11-11 19:10:28 +0000691 class ModuleMapParser {
692 Lexer &L;
693 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000694
695 /// \brief Default target information, used only for string literal
696 /// parsing.
697 const TargetInfo *Target;
698
Douglas Gregora30cfe52011-11-11 19:10:28 +0000699 DiagnosticsEngine &Diags;
700 ModuleMap &Map;
701
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000702 /// \brief The directory that this module map resides in.
703 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000704
705 /// \brief The directory containing Clang-supplied headers.
706 const DirectoryEntry *BuiltinIncludeDir;
707
Douglas Gregora30cfe52011-11-11 19:10:28 +0000708 /// \brief Whether an error occurred.
709 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000710
Douglas Gregora30cfe52011-11-11 19:10:28 +0000711 /// \brief Stores string data for the various string literals referenced
712 /// during parsing.
713 llvm::BumpPtrAllocator StringData;
714
715 /// \brief The current token.
716 MMToken Tok;
717
718 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000719 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000720
721 /// \brief Consume the current token and return its location.
722 SourceLocation consumeToken();
723
724 /// \brief Skip tokens until we reach the a token with the given kind
725 /// (or the end of the file).
726 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000727
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000728 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000729 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000730 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000731 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000732 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000733 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000734 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000735 void parseLinkDecl();
Douglas Gregor82e52372012-11-06 19:39:40 +0000736 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000737 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000738
Douglas Gregor6a1db482011-12-09 02:04:43 +0000739 const DirectoryEntry *getOverriddenHeaderSearchDir();
740
Douglas Gregora30cfe52011-11-11 19:10:28 +0000741 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000742 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000743 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000744 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000745 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000746 const DirectoryEntry *Directory,
747 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000748 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000749 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
750 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000751 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000752 Tok.clear();
753 consumeToken();
754 }
755
756 bool parseModuleMapFile();
757 };
758}
759
760SourceLocation ModuleMapParser::consumeToken() {
761retry:
762 SourceLocation Result = Tok.getLocation();
763 Tok.clear();
764
765 Token LToken;
766 L.LexFromRawLexer(LToken);
767 Tok.Location = LToken.getLocation().getRawEncoding();
768 switch (LToken.getKind()) {
769 case tok::raw_identifier:
770 Tok.StringData = LToken.getRawIdentifierData();
771 Tok.StringLength = LToken.getLength();
772 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
773 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000774 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000775 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000776 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000777 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000778 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000779 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000780 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000781 .Case("umbrella", MMToken::UmbrellaKeyword)
782 .Default(MMToken::Identifier);
783 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000784
785 case tok::comma:
786 Tok.Kind = MMToken::Comma;
787 break;
788
Douglas Gregora30cfe52011-11-11 19:10:28 +0000789 case tok::eof:
790 Tok.Kind = MMToken::EndOfFile;
791 break;
792
793 case tok::l_brace:
794 Tok.Kind = MMToken::LBrace;
795 break;
796
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000797 case tok::l_square:
798 Tok.Kind = MMToken::LSquare;
799 break;
800
Douglas Gregor90db2602011-12-02 01:47:07 +0000801 case tok::period:
802 Tok.Kind = MMToken::Period;
803 break;
804
Douglas Gregora30cfe52011-11-11 19:10:28 +0000805 case tok::r_brace:
806 Tok.Kind = MMToken::RBrace;
807 break;
808
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000809 case tok::r_square:
810 Tok.Kind = MMToken::RSquare;
811 break;
812
Douglas Gregor90db2602011-12-02 01:47:07 +0000813 case tok::star:
814 Tok.Kind = MMToken::Star;
815 break;
816
Douglas Gregora30cfe52011-11-11 19:10:28 +0000817 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000818 if (LToken.hasUDSuffix()) {
819 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
820 HadError = true;
821 goto retry;
822 }
823
Douglas Gregora30cfe52011-11-11 19:10:28 +0000824 // Parse the string literal.
825 LangOptions LangOpts;
826 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
827 if (StringLiteral.hadError)
828 goto retry;
829
830 // Copy the string literal into our string data allocator.
831 unsigned Length = StringLiteral.GetStringLength();
832 char *Saved = StringData.Allocate<char>(Length + 1);
833 memcpy(Saved, StringLiteral.GetString().data(), Length);
834 Saved[Length] = 0;
835
836 // Form the token.
837 Tok.Kind = MMToken::StringLiteral;
838 Tok.StringData = Saved;
839 Tok.StringLength = Length;
840 break;
841 }
842
843 case tok::comment:
844 goto retry;
845
846 default:
847 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
848 HadError = true;
849 goto retry;
850 }
851
852 return Result;
853}
854
855void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
856 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000857 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000858 do {
859 switch (Tok.Kind) {
860 case MMToken::EndOfFile:
861 return;
862
863 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000864 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000865 return;
866
867 ++braceDepth;
868 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000869
870 case MMToken::LSquare:
871 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
872 return;
873
874 ++squareDepth;
875 break;
876
Douglas Gregora30cfe52011-11-11 19:10:28 +0000877 case MMToken::RBrace:
878 if (braceDepth > 0)
879 --braceDepth;
880 else if (Tok.is(K))
881 return;
882 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000883
884 case MMToken::RSquare:
885 if (squareDepth > 0)
886 --squareDepth;
887 else if (Tok.is(K))
888 return;
889 break;
890
Douglas Gregora30cfe52011-11-11 19:10:28 +0000891 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000892 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000893 return;
894 break;
895 }
896
897 consumeToken();
898 } while (true);
899}
900
Douglas Gregor587986e2011-12-07 02:23:45 +0000901/// \brief Parse a module-id.
902///
903/// module-id:
904/// identifier
905/// identifier '.' module-id
906///
907/// \returns true if an error occurred, false otherwise.
908bool ModuleMapParser::parseModuleId(ModuleId &Id) {
909 Id.clear();
910 do {
911 if (Tok.is(MMToken::Identifier)) {
912 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
913 consumeToken();
914 } else {
915 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
916 return true;
917 }
918
919 if (!Tok.is(MMToken::Period))
920 break;
921
922 consumeToken();
923 } while (true);
924
925 return false;
926}
927
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000928namespace {
929 /// \brief Enumerates the known attributes.
930 enum AttributeKind {
931 /// \brief An unknown attribute.
932 AT_unknown,
933 /// \brief The 'system' attribute.
934 AT_system
935 };
936}
937
Douglas Gregora30cfe52011-11-11 19:10:28 +0000938/// \brief Parse a module declaration.
939///
940/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000941/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
942/// { module-member* }
943///
Douglas Gregora30cfe52011-11-11 19:10:28 +0000944/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +0000945/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000946/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +0000947/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +0000948/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000949/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +0000950///
951/// submodule-declaration:
952/// module-declaration
953/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000954void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +0000955 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
956 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +0000957 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +0000958 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000959 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +0000960 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +0000961
Douglas Gregord620a842011-12-06 17:16:41 +0000962 // Parse 'explicit' keyword, if present.
963 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +0000964 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +0000965 Explicit = true;
966 }
967
968 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +0000969 if (Tok.is(MMToken::FrameworkKeyword)) {
970 consumeToken();
971 Framework = true;
972 }
Douglas Gregora30cfe52011-11-11 19:10:28 +0000973
974 // Parse 'module' keyword.
975 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +0000976 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000977 consumeToken();
978 HadError = true;
979 return;
980 }
981 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +0000982
983 // If we have a wildcard for the module name, this is an inferred submodule.
984 // Parse it.
985 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +0000986 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000987
988 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +0000989 ModuleId Id;
990 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000991 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +0000992 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000993 }
Douglas Gregor82e52372012-11-06 19:39:40 +0000994
Douglas Gregor587986e2011-12-07 02:23:45 +0000995 if (ActiveModule) {
996 if (Id.size() > 1) {
997 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
998 << SourceRange(Id.front().second, Id.back().second);
999
1000 HadError = true;
1001 return;
1002 }
1003 } else if (Id.size() == 1 && Explicit) {
1004 // Top-level modules can't be explicit.
1005 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1006 Explicit = false;
1007 ExplicitLoc = SourceLocation();
1008 HadError = true;
1009 }
1010
1011 Module *PreviousActiveModule = ActiveModule;
1012 if (Id.size() > 1) {
1013 // This module map defines a submodule. Go find the module of which it
1014 // is a submodule.
1015 ActiveModule = 0;
1016 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1017 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1018 ActiveModule = Next;
1019 continue;
1020 }
1021
1022 if (ActiveModule) {
1023 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1024 << Id[I].first << ActiveModule->getTopLevelModule();
1025 } else {
1026 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1027 }
1028 HadError = true;
1029 return;
1030 }
1031 }
1032
1033 StringRef ModuleName = Id.back().first;
1034 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001035
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001036 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001037 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001038 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001039
Douglas Gregora30cfe52011-11-11 19:10:28 +00001040 // Parse the opening brace.
1041 if (!Tok.is(MMToken::LBrace)) {
1042 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1043 << ModuleName;
1044 HadError = true;
1045 return;
1046 }
1047 SourceLocation LBraceLoc = consumeToken();
1048
1049 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001050 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001051 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1052 // Skip the module definition.
1053 skipUntil(MMToken::RBrace);
1054 if (Tok.is(MMToken::RBrace))
1055 consumeToken();
1056 else {
1057 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1058 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1059 HadError = true;
1060 }
1061 return;
1062 }
1063
Douglas Gregora30cfe52011-11-11 19:10:28 +00001064 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1065 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001066 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001067
1068 // Skip the module definition.
1069 skipUntil(MMToken::RBrace);
1070 if (Tok.is(MMToken::RBrace))
1071 consumeToken();
1072
1073 HadError = true;
1074 return;
1075 }
1076
1077 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001078 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1079 Explicit).first;
1080 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001081 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001082 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001083
1084 bool Done = false;
1085 do {
1086 switch (Tok.Kind) {
1087 case MMToken::EndOfFile:
1088 case MMToken::RBrace:
1089 Done = true;
1090 break;
1091
1092 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001093 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001094 case MMToken::ModuleKeyword:
1095 parseModuleDecl();
1096 break;
1097
Douglas Gregor90db2602011-12-02 01:47:07 +00001098 case MMToken::ExportKeyword:
1099 parseExportDecl();
1100 break;
1101
Douglas Gregor51f564f2011-12-31 04:05:44 +00001102 case MMToken::RequiresKeyword:
1103 parseRequiresDecl();
1104 break;
1105
Douglas Gregor77d029f2011-12-08 19:11:24 +00001106 case MMToken::UmbrellaKeyword: {
1107 SourceLocation UmbrellaLoc = consumeToken();
1108 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001109 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001110 else
1111 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001112 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001113 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001114
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001115 case MMToken::ExcludeKeyword: {
1116 SourceLocation ExcludeLoc = consumeToken();
1117 if (Tok.is(MMToken::HeaderKeyword)) {
1118 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1119 } else {
1120 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1121 << "exclude";
1122 }
1123 break;
1124 }
1125
Douglas Gregor489ad432011-12-08 18:00:48 +00001126 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001127 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001128 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001129
1130 case MMToken::LinkKeyword:
1131 parseLinkDecl();
1132 break;
1133
Douglas Gregora30cfe52011-11-11 19:10:28 +00001134 default:
1135 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1136 consumeToken();
1137 break;
1138 }
1139 } while (!Done);
1140
1141 if (Tok.is(MMToken::RBrace))
1142 consumeToken();
1143 else {
1144 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1145 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1146 HadError = true;
1147 }
1148
Douglas Gregor8767dc22013-01-14 17:57:51 +00001149 // If the active module is a top-level framework, and there are no link
1150 // libraries, automatically link against the framework.
1151 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1152 ActiveModule->LinkLibraries.empty()) {
1153 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1154 }
1155
Douglas Gregor587986e2011-12-07 02:23:45 +00001156 // We're done parsing this module. Pop back to the previous module.
1157 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001158}
Douglas Gregord620a842011-12-06 17:16:41 +00001159
Douglas Gregor51f564f2011-12-31 04:05:44 +00001160/// \brief Parse a requires declaration.
1161///
1162/// requires-declaration:
1163/// 'requires' feature-list
1164///
1165/// feature-list:
1166/// identifier ',' feature-list
1167/// identifier
1168void ModuleMapParser::parseRequiresDecl() {
1169 assert(Tok.is(MMToken::RequiresKeyword));
1170
1171 // Parse 'requires' keyword.
1172 consumeToken();
1173
1174 // Parse the feature-list.
1175 do {
1176 if (!Tok.is(MMToken::Identifier)) {
1177 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1178 HadError = true;
1179 return;
1180 }
1181
1182 // Consume the feature name.
1183 std::string Feature = Tok.getString();
1184 consumeToken();
1185
1186 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001187 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001188
1189 if (!Tok.is(MMToken::Comma))
1190 break;
1191
1192 // Consume the comma.
1193 consumeToken();
1194 } while (true);
1195}
1196
Douglas Gregord620a842011-12-06 17:16:41 +00001197/// \brief Append to \p Paths the set of paths needed to get to the
1198/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001199static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001200 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001201 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001202 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001203 for (; Mod; Mod = Mod->Parent) {
1204 if (Mod->IsFramework)
1205 Paths.push_back(Mod->Name);
1206 }
1207
1208 if (Paths.empty())
1209 return;
1210
1211 // Add Frameworks/Name.framework for each subframework.
1212 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1213 llvm::sys::path::append(Path, "Frameworks");
1214 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1215 }
1216}
1217
Douglas Gregor2f04f182012-02-02 18:42:48 +00001218/// \brief Determine whether the given file name is the name of a builtin
1219/// header, supplied by Clang to replace, override, or augment existing system
1220/// headers.
1221static bool isBuiltinHeader(StringRef FileName) {
1222 return llvm::StringSwitch<bool>(FileName)
1223 .Case("float.h", true)
1224 .Case("iso646.h", true)
1225 .Case("limits.h", true)
1226 .Case("stdalign.h", true)
1227 .Case("stdarg.h", true)
1228 .Case("stdbool.h", true)
1229 .Case("stddef.h", true)
1230 .Case("stdint.h", true)
1231 .Case("tgmath.h", true)
1232 .Case("unwind.h", true)
1233 .Default(false);
1234}
1235
Douglas Gregora30cfe52011-11-11 19:10:28 +00001236/// \brief Parse a header declaration.
1237///
1238/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001239/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001240/// 'exclude'[opt] 'header' string-literal
1241void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1242 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001243 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001244 consumeToken();
1245
Douglas Gregor489ad432011-12-08 18:00:48 +00001246 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001247 bool Exclude = ExcludeLoc.isValid();
1248 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001249 // Parse the header name.
1250 if (!Tok.is(MMToken::StringLiteral)) {
1251 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1252 << "header";
1253 HadError = true;
1254 return;
1255 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001256 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001257 SourceLocation FileNameLoc = consumeToken();
1258
Douglas Gregor77d029f2011-12-08 19:11:24 +00001259 // Check whether we already have an umbrella.
1260 if (Umbrella && ActiveModule->Umbrella) {
1261 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1262 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001263 HadError = true;
1264 return;
1265 }
1266
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001267 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001268 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001269 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001270 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001271 if (llvm::sys::path::is_absolute(FileName)) {
1272 PathName = FileName;
1273 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001274 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1275 PathName = Dir->getName();
1276 llvm::sys::path::append(PathName, FileName);
1277 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001278 } else {
1279 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001280 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001281 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001282
Douglas Gregord620a842011-12-06 17:16:41 +00001283 if (ActiveModule->isPartOfFramework()) {
1284 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001285
1286 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001287 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001288 llvm::sys::path::append(PathName, FileName);
1289 File = SourceMgr.getFileManager().getFile(PathName);
1290
1291 if (!File) {
1292 // Check whether this file is in the private headers.
1293 PathName.resize(PathLength);
1294 llvm::sys::path::append(PathName, "PrivateHeaders");
1295 llvm::sys::path::append(PathName, FileName);
1296 File = SourceMgr.getFileManager().getFile(PathName);
1297 }
1298 } else {
1299 // Lookup for normal headers.
1300 llvm::sys::path::append(PathName, FileName);
1301 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001302
1303 // If this is a system module with a top-level header, this header
1304 // may have a counterpart (or replacement) in the set of headers
1305 // supplied by Clang. Find that builtin header.
1306 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1307 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001308 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001309 llvm::sys::path::append(BuiltinPathName, FileName);
1310 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1311
1312 // If Clang supplies this header but the underlying system does not,
1313 // just silently swap in our builtin version. Otherwise, we'll end
1314 // up adding both (later).
1315 if (!File && BuiltinFile) {
1316 File = BuiltinFile;
1317 BuiltinFile = 0;
1318 }
1319 }
Douglas Gregord620a842011-12-06 17:16:41 +00001320 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001321 }
Douglas Gregora8654052011-11-17 22:09:43 +00001322
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001323 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1324 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001325 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001326 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001327 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001328 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001329 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001330 } else if (Umbrella) {
1331 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001332 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001333 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001334 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001335 HadError = true;
1336 } else {
1337 // Record this umbrella header.
1338 Map.setUmbrellaHeader(ActiveModule, File);
1339 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001340 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001341 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001342 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001343
1344 // If there is a builtin counterpart to this file, add it now.
1345 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001346 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001347 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001348 } else if (!Exclude) {
1349 // Ignore excluded header files. They're optional anyway.
1350
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001351 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001352 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001353 HadError = true;
1354 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001355}
1356
Douglas Gregor77d029f2011-12-08 19:11:24 +00001357/// \brief Parse an umbrella directory declaration.
1358///
1359/// umbrella-dir-declaration:
1360/// umbrella string-literal
1361void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1362 // Parse the directory name.
1363 if (!Tok.is(MMToken::StringLiteral)) {
1364 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1365 << "umbrella";
1366 HadError = true;
1367 return;
1368 }
1369
1370 std::string DirName = Tok.getString();
1371 SourceLocation DirNameLoc = consumeToken();
1372
1373 // Check whether we already have an umbrella.
1374 if (ActiveModule->Umbrella) {
1375 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1376 << ActiveModule->getFullModuleName();
1377 HadError = true;
1378 return;
1379 }
1380
1381 // Look for this file.
1382 const DirectoryEntry *Dir = 0;
1383 if (llvm::sys::path::is_absolute(DirName))
1384 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1385 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001386 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001387 PathName = Directory->getName();
1388 llvm::sys::path::append(PathName, DirName);
1389 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1390 }
1391
1392 if (!Dir) {
1393 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1394 << DirName;
1395 HadError = true;
1396 return;
1397 }
1398
1399 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1400 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1401 << OwningModule->getFullModuleName();
1402 HadError = true;
1403 return;
1404 }
1405
1406 // Record this umbrella directory.
1407 Map.setUmbrellaDir(ActiveModule, Dir);
1408}
1409
Douglas Gregor90db2602011-12-02 01:47:07 +00001410/// \brief Parse a module export declaration.
1411///
1412/// export-declaration:
1413/// 'export' wildcard-module-id
1414///
1415/// wildcard-module-id:
1416/// identifier
1417/// '*'
1418/// identifier '.' wildcard-module-id
1419void ModuleMapParser::parseExportDecl() {
1420 assert(Tok.is(MMToken::ExportKeyword));
1421 SourceLocation ExportLoc = consumeToken();
1422
1423 // Parse the module-id with an optional wildcard at the end.
1424 ModuleId ParsedModuleId;
1425 bool Wildcard = false;
1426 do {
1427 if (Tok.is(MMToken::Identifier)) {
1428 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1429 Tok.getLocation()));
1430 consumeToken();
1431
1432 if (Tok.is(MMToken::Period)) {
1433 consumeToken();
1434 continue;
1435 }
1436
1437 break;
1438 }
1439
1440 if(Tok.is(MMToken::Star)) {
1441 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001442 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001443 break;
1444 }
1445
1446 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1447 HadError = true;
1448 return;
1449 } while (true);
1450
1451 Module::UnresolvedExportDecl Unresolved = {
1452 ExportLoc, ParsedModuleId, Wildcard
1453 };
1454 ActiveModule->UnresolvedExports.push_back(Unresolved);
1455}
1456
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001457/// \brief Parse a link declaration.
1458///
1459/// module-declaration:
1460/// 'link' 'framework'[opt] string-literal
1461void ModuleMapParser::parseLinkDecl() {
1462 assert(Tok.is(MMToken::LinkKeyword));
1463 SourceLocation LinkLoc = consumeToken();
1464
1465 // Parse the optional 'framework' keyword.
1466 bool IsFramework = false;
1467 if (Tok.is(MMToken::FrameworkKeyword)) {
1468 consumeToken();
1469 IsFramework = true;
1470 }
1471
1472 // Parse the library name
1473 if (!Tok.is(MMToken::StringLiteral)) {
1474 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1475 << IsFramework << SourceRange(LinkLoc);
1476 HadError = true;
1477 return;
1478 }
1479
1480 std::string LibraryName = Tok.getString();
1481 consumeToken();
1482 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1483 IsFramework));
1484}
1485
1486/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001487///
1488/// module-declaration:
1489/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1490/// { inferred-module-member* }
1491///
1492/// inferred-module-member:
1493/// 'export' '*'
1494/// 'exclude' identifier
1495void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001496 assert(Tok.is(MMToken::Star));
1497 SourceLocation StarLoc = consumeToken();
1498 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001499
Douglas Gregor1e123682011-12-05 22:27:44 +00001500 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001501 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001502 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1503 Failed = true;
1504 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001505
1506 if (ActiveModule) {
1507 // Inferred modules must have umbrella directories.
1508 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1509 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1510 Failed = true;
1511 }
1512
1513 // Check for redefinition of an inferred module.
1514 if (!Failed && ActiveModule->InferSubmodules) {
1515 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1516 if (ActiveModule->InferredSubmoduleLoc.isValid())
1517 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1518 diag::note_mmap_prev_definition);
1519 Failed = true;
1520 }
1521
1522 // Check for the 'framework' keyword, which is not permitted here.
1523 if (Framework) {
1524 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1525 Framework = false;
1526 }
1527 } else if (Explicit) {
1528 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1529 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001530 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001531
Douglas Gregor1e123682011-12-05 22:27:44 +00001532 // If there were any problems with this inferred submodule, skip its body.
1533 if (Failed) {
1534 if (Tok.is(MMToken::LBrace)) {
1535 consumeToken();
1536 skipUntil(MMToken::RBrace);
1537 if (Tok.is(MMToken::RBrace))
1538 consumeToken();
1539 }
1540 HadError = true;
1541 return;
1542 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001543
1544 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001545 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001546 parseOptionalAttributes(Attrs);
1547
1548 if (ActiveModule) {
1549 // Note that we have an inferred submodule.
1550 ActiveModule->InferSubmodules = true;
1551 ActiveModule->InferredSubmoduleLoc = StarLoc;
1552 ActiveModule->InferExplicitSubmodules = Explicit;
1553 } else {
1554 // We'll be inferring framework modules for this directory.
1555 Map.InferredDirectories[Directory].InferModules = true;
1556 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1557 }
1558
Douglas Gregor1e123682011-12-05 22:27:44 +00001559 // Parse the opening brace.
1560 if (!Tok.is(MMToken::LBrace)) {
1561 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1562 HadError = true;
1563 return;
1564 }
1565 SourceLocation LBraceLoc = consumeToken();
1566
1567 // Parse the body of the inferred submodule.
1568 bool Done = false;
1569 do {
1570 switch (Tok.Kind) {
1571 case MMToken::EndOfFile:
1572 case MMToken::RBrace:
1573 Done = true;
1574 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001575
1576 case MMToken::ExcludeKeyword: {
1577 if (ActiveModule) {
1578 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001579 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001580 consumeToken();
1581 break;
1582 }
1583
1584 consumeToken();
1585 if (!Tok.is(MMToken::Identifier)) {
1586 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1587 break;
1588 }
1589
1590 Map.InferredDirectories[Directory].ExcludedModules
1591 .push_back(Tok.getString());
1592 consumeToken();
1593 break;
1594 }
1595
1596 case MMToken::ExportKeyword:
1597 if (!ActiveModule) {
1598 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001599 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001600 consumeToken();
1601 break;
1602 }
1603
Douglas Gregor1e123682011-12-05 22:27:44 +00001604 consumeToken();
1605 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001606 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001607 else
1608 Diags.Report(Tok.getLocation(),
1609 diag::err_mmap_expected_export_wildcard);
1610 consumeToken();
1611 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001612
Douglas Gregor1e123682011-12-05 22:27:44 +00001613 case MMToken::ExplicitKeyword:
1614 case MMToken::ModuleKeyword:
1615 case MMToken::HeaderKeyword:
1616 case MMToken::UmbrellaKeyword:
1617 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001618 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001619 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001620 consumeToken();
1621 break;
1622 }
1623 } while (!Done);
1624
1625 if (Tok.is(MMToken::RBrace))
1626 consumeToken();
1627 else {
1628 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1629 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1630 HadError = true;
1631 }
1632}
1633
Douglas Gregor82e52372012-11-06 19:39:40 +00001634/// \brief Parse optional attributes.
1635///
1636/// attributes:
1637/// attribute attributes
1638/// attribute
1639///
1640/// attribute:
1641/// [ identifier ]
1642///
1643/// \param Attrs Will be filled in with the parsed attributes.
1644///
1645/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001646bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001647 bool HadError = false;
1648
1649 while (Tok.is(MMToken::LSquare)) {
1650 // Consume the '['.
1651 SourceLocation LSquareLoc = consumeToken();
1652
1653 // Check whether we have an attribute name here.
1654 if (!Tok.is(MMToken::Identifier)) {
1655 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1656 skipUntil(MMToken::RSquare);
1657 if (Tok.is(MMToken::RSquare))
1658 consumeToken();
1659 HadError = true;
1660 }
1661
1662 // Decode the attribute name.
1663 AttributeKind Attribute
1664 = llvm::StringSwitch<AttributeKind>(Tok.getString())
1665 .Case("system", AT_system)
1666 .Default(AT_unknown);
1667 switch (Attribute) {
1668 case AT_unknown:
1669 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1670 << Tok.getString();
1671 break;
1672
1673 case AT_system:
1674 Attrs.IsSystem = true;
1675 break;
1676 }
1677 consumeToken();
1678
1679 // Consume the ']'.
1680 if (!Tok.is(MMToken::RSquare)) {
1681 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1682 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1683 skipUntil(MMToken::RSquare);
1684 HadError = true;
1685 }
1686
1687 if (Tok.is(MMToken::RSquare))
1688 consumeToken();
1689 }
1690
1691 return HadError;
1692}
1693
Douglas Gregor6a1db482011-12-09 02:04:43 +00001694/// \brief If there is a specific header search directory due the presence
1695/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1696const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1697 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1698 // If we have an umbrella directory, use that.
1699 if (Mod->hasUmbrellaDir())
1700 return Mod->getUmbrellaDir();
1701
1702 // If we have a framework directory, stop looking.
1703 if (Mod->IsFramework)
1704 return 0;
1705 }
1706
1707 return 0;
1708}
1709
Douglas Gregora30cfe52011-11-11 19:10:28 +00001710/// \brief Parse a module map file.
1711///
1712/// module-map-file:
1713/// module-declaration*
1714bool ModuleMapParser::parseModuleMapFile() {
1715 do {
1716 switch (Tok.Kind) {
1717 case MMToken::EndOfFile:
1718 return HadError;
1719
Douglas Gregor587986e2011-12-07 02:23:45 +00001720 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001721 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001722 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001723 parseModuleDecl();
1724 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001725
Douglas Gregor51f564f2011-12-31 04:05:44 +00001726 case MMToken::Comma:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001727 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001728 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001729 case MMToken::HeaderKeyword:
1730 case MMToken::Identifier:
1731 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001732 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001733 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001734 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001735 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001736 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001737 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001738 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001739 case MMToken::StringLiteral:
1740 case MMToken::UmbrellaKeyword:
1741 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1742 HadError = true;
1743 consumeToken();
1744 break;
1745 }
1746 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001747}
1748
1749bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001750 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1751 = ParsedModuleMap.find(File);
1752 if (Known != ParsedModuleMap.end())
1753 return Known->second;
1754
Douglas Gregordc58aa72012-01-30 06:01:29 +00001755 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001756 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1757 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1758 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001759 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001760
1761 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001762 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1763 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001764 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001765 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001766 bool Result = Parser.parseModuleMapFile();
1767 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001768 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001769 return Result;
1770}