blob: 2f40e24175cbfeea25b7189c4a8f1512f5828b39 [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)
Dmitri Gribenkoadeb7822013-01-26 16:29:36 +000032#include <limits.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000033#endif
Douglas Gregora30cfe52011-11-11 19:10:28 +000034using namespace clang;
35
Douglas Gregor90db2602011-12-02 01:47:07 +000036Module::ExportDecl
37ModuleMap::resolveExport(Module *Mod,
38 const Module::UnresolvedExportDecl &Unresolved,
39 bool Complain) {
Douglas Gregor0adaa882011-12-05 17:28:06 +000040 // We may have just a wildcard.
41 if (Unresolved.Id.empty()) {
42 assert(Unresolved.Wildcard && "Invalid unresolved export");
43 return Module::ExportDecl(0, true);
44 }
45
Douglas Gregor90db2602011-12-02 01:47:07 +000046 // Find the starting module.
47 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
48 if (!Context) {
49 if (Complain)
50 Diags->Report(Unresolved.Id[0].second,
51 diag::err_mmap_missing_module_unqualified)
52 << Unresolved.Id[0].first << Mod->getFullModuleName();
53
54 return Module::ExportDecl();
55 }
56
57 // Dig into the module path.
58 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
59 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
60 Context);
61 if (!Sub) {
62 if (Complain)
63 Diags->Report(Unresolved.Id[I].second,
64 diag::err_mmap_missing_module_qualified)
65 << Unresolved.Id[I].first << Context->getFullModuleName()
66 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
67
68 return Module::ExportDecl();
69 }
70
71 Context = Sub;
72 }
73
74 return Module::ExportDecl(Context, Unresolved.Wildcard);
75}
76
Douglas Gregor51f564f2011-12-31 04:05:44 +000077ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
Douglas Gregordc58aa72012-01-30 06:01:29 +000078 const LangOptions &LangOpts, const TargetInfo *Target)
Douglas Gregor2f04f182012-02-02 18:42:48 +000079 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000080{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000081 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
82 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000083 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora30cfe52011-11-11 19:10:28 +000084 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
85 SourceMgr = new SourceManager(*Diags, FileMgr);
86}
87
88ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +000089 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
90 IEnd = Modules.end();
91 I != IEnd; ++I) {
92 delete I->getValue();
93 }
94
Douglas Gregora30cfe52011-11-11 19:10:28 +000095 delete SourceMgr;
96}
97
Douglas Gregordc58aa72012-01-30 06:01:29 +000098void ModuleMap::setTarget(const TargetInfo &Target) {
99 assert((!this->Target || this->Target == &Target) &&
100 "Improper target override");
101 this->Target = &Target;
102}
103
Douglas Gregor8b48e082012-10-12 21:15:50 +0000104/// \brief "Sanitize" a filename so that it can be used as an identifier.
105static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
106 SmallVectorImpl<char> &Buffer) {
107 if (Name.empty())
108 return Name;
109
110 // Check whether the filename is already an identifier; this is the common
111 // case.
112 bool isIdentifier = true;
113 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
114 if (isalpha(Name[I]) || Name[I] == '_' || (isdigit(Name[I]) && I > 0))
115 continue;
116
117 isIdentifier = false;
118 break;
119 }
120
121 if (!isIdentifier) {
122 // If we don't already have something with the form of an identifier,
123 // create a buffer with the sanitized name.
124 Buffer.clear();
125 if (isdigit(Name[0]))
126 Buffer.push_back('_');
127 Buffer.reserve(Buffer.size() + Name.size());
128 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
129 if (isalnum(Name[I]) || isspace(Name[I]))
130 Buffer.push_back(Name[I]);
131 else
132 Buffer.push_back('_');
133 }
134
135 Name = StringRef(Buffer.data(), Buffer.size());
136 }
137
138 while (llvm::StringSwitch<bool>(Name)
139#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
140#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
141#include "clang/Basic/TokenKinds.def"
142 .Default(false)) {
143 if (Name.data() != Buffer.data())
144 Buffer.append(Name.begin(), Name.end());
145 Buffer.push_back('_');
146 Name = StringRef(Buffer.data(), Buffer.size());
147 }
148
149 return Name;
150}
151
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000152Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000153 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000154 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000155 // If a header is not available, don't report that it maps to anything.
156 if (!Known->second.isAvailable())
Douglas Gregor51f564f2011-12-31 04:05:44 +0000157 return 0;
158
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000159 return Known->second.getModule();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000160 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000161
Douglas Gregoradb97992011-11-16 23:02:25 +0000162 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000163 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000164
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000165 // Note: as an egregious but useful hack we use the real path here, because
166 // frameworks moving from top-level frameworks to embedded frameworks tend
167 // to be symlinked from the top-level location to the embedded location,
168 // and we need to resolve lookups as if we had found the embedded location.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000169 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000170
171 // Keep walking up the directory hierarchy, looking for a directory with
172 // an umbrella header.
173 do {
174 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
175 = UmbrellaDirs.find(Dir);
176 if (KnownDir != UmbrellaDirs.end()) {
177 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000178
179 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000180 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000181 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000182 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000183 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000184
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000185 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000186 // Infer submodules for each of the directories we found between
187 // the directory of the umbrella header and the directory where
188 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000189 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000190
Douglas Gregor6a1db482011-12-09 02:04:43 +0000191 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000192 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000193 SmallString<32> NameBuf;
194 StringRef Name = sanitizeFilenameAsIdentifier(
195 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
196 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000197 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000198 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000199
200 // Associate the module and the directory.
201 UmbrellaDirs[SkippedDirs[I-1]] = Result;
202
203 // If inferred submodules export everything they import, add a
204 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000205 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000206 Result->Exports.push_back(Module::ExportDecl(0, true));
207 }
208
209 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000210 SmallString<32> NameBuf;
211 StringRef Name = sanitizeFilenameAsIdentifier(
212 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000213 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000214 Explicit).first;
Argyrios Kyrtzidisc7782d92012-10-05 00:22:33 +0000215 Result->TopHeaders.insert(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000216
217 // If inferred submodules export everything they import, add a
218 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000219 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000220 Result->Exports.push_back(Module::ExportDecl(0, true));
221 } else {
222 // Record each of the directories we stepped through as being part of
223 // the module we found, since the umbrella header covers them all.
224 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
225 UmbrellaDirs[SkippedDirs[I]] = Result;
226 }
227
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000228 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000229
230 // If a header corresponds to an unavailable module, don't report
231 // that it maps to anything.
232 if (!Result->isAvailable())
233 return 0;
234
Douglas Gregore209e502011-12-06 01:10:29 +0000235 return Result;
236 }
237
238 SkippedDirs.push_back(Dir);
239
Douglas Gregoradb97992011-11-16 23:02:25 +0000240 // Retrieve our parent path.
241 DirName = llvm::sys::path::parent_path(DirName);
242 if (DirName.empty())
243 break;
244
245 // Resolve the parent path to a directory entry.
246 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000247 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000248
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000249 return 0;
250}
251
Douglas Gregor51f564f2011-12-31 04:05:44 +0000252bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000253 HeadersMap::iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000254 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000255 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000256
257 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000258 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000259 StringRef DirName = Dir->getName();
260
261 // Keep walking up the directory hierarchy, looking for a directory with
262 // an umbrella header.
263 do {
264 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
265 = UmbrellaDirs.find(Dir);
266 if (KnownDir != UmbrellaDirs.end()) {
267 Module *Found = KnownDir->second;
268 if (!Found->isAvailable())
269 return true;
270
271 // Search up the module stack until we find a module with an umbrella
272 // directory.
273 Module *UmbrellaModule = Found;
274 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
275 UmbrellaModule = UmbrellaModule->Parent;
276
277 if (UmbrellaModule->InferSubmodules) {
278 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
279 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000280 SmallString<32> NameBuf;
281 StringRef Name = sanitizeFilenameAsIdentifier(
282 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
283 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000284 Found = lookupModuleQualified(Name, Found);
285 if (!Found)
286 return false;
287 if (!Found->isAvailable())
288 return true;
289 }
290
291 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000292 SmallString<32> NameBuf;
293 StringRef Name = sanitizeFilenameAsIdentifier(
294 llvm::sys::path::stem(Header->getName()),
295 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000296 Found = lookupModuleQualified(Name, Found);
297 if (!Found)
298 return false;
299 }
300
301 return !Found->isAvailable();
302 }
303
304 SkippedDirs.push_back(Dir);
305
306 // Retrieve our parent path.
307 DirName = llvm::sys::path::parent_path(DirName);
308 if (DirName.empty())
309 break;
310
311 // Resolve the parent path to a directory entry.
312 Dir = SourceMgr->getFileManager().getDirectory(DirName);
313 } while (Dir);
314
315 return false;
316}
317
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000318Module *ModuleMap::findModule(StringRef Name) {
Douglas Gregor484535e2011-11-11 23:20:24 +0000319 llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
320 if (Known != Modules.end())
321 return Known->getValue();
322
323 return 0;
324}
325
Douglas Gregor90db2602011-12-02 01:47:07 +0000326Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
327 for(; Context; Context = Context->Parent) {
328 if (Module *Sub = lookupModuleQualified(Name, Context))
329 return Sub;
330 }
331
332 return findModule(Name);
333}
334
335Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
336 if (!Context)
337 return findModule(Name);
338
Douglas Gregorb7a78192012-01-04 23:32:19 +0000339 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000340}
341
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000342std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000343ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
344 bool IsExplicit) {
345 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000346 if (Module *Sub = lookupModuleQualified(Name, Parent))
347 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000348
349 // Create a new module with this name.
350 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
351 IsExplicit);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000352 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000353 Modules[Name] = Result;
354 return std::make_pair(Result, true);
355}
356
Douglas Gregor82e52372012-11-06 19:39:40 +0000357bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
358 StringRef Name, bool &IsSystem) {
359 // Check whether we have already looked into the parent directory
360 // for a module map.
361 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
362 inferred = InferredDirectories.find(ParentDir);
363 if (inferred == InferredDirectories.end())
364 return false;
365
366 if (!inferred->second.InferModules)
367 return false;
368
369 // We're allowed to infer for this directory, but make sure it's okay
370 // to infer this particular module.
371 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
372 inferred->second.ExcludedModules.end(),
373 Name) == inferred->second.ExcludedModules.end();
374
375 if (canInfer && inferred->second.InferSystemModules)
376 IsSystem = true;
377
378 return canInfer;
379}
380
Douglas Gregor8767dc22013-01-14 17:57:51 +0000381/// \brief For a framework module, infer the framework against which we
382/// should link.
383static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
384 FileManager &FileMgr) {
385 assert(Mod->IsFramework && "Can only infer linking for framework modules");
386 assert(!Mod->isSubFramework() &&
387 "Can only infer linking for top-level frameworks");
388
389 SmallString<128> LibName;
390 LibName += FrameworkDir->getName();
391 llvm::sys::path::append(LibName, Mod->Name);
392 if (FileMgr.getFile(LibName)) {
393 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
394 /*IsFramework=*/true));
395 }
396}
397
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000398Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000399ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000400 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000401 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000402 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000403 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000404 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
405 return Mod;
406
407 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000408
409 // If the framework has a parent path from which we're allowed to infer
410 // a framework module, do so.
411 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000412 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000413
Douglas Gregor7005b902013-01-10 01:43:00 +0000414 // Note: as an egregious but useful hack we use the real path here, because
415 // we might be looking at an embedded framework that symlinks out to a
416 // top-level framework, and we need to infer as if we were naming the
417 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000418 StringRef FrameworkDirName
419 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000420
Douglas Gregor82e52372012-11-06 19:39:40 +0000421 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000422 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000423 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000424 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000425 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
426 // Check whether we have already looked into the parent directory
427 // for a module map.
428 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
429 inferred = InferredDirectories.find(ParentDir);
430 if (inferred == InferredDirectories.end()) {
431 // We haven't looked here before. Load a module map, if there is
432 // one.
433 SmallString<128> ModMapPath = Parent;
434 llvm::sys::path::append(ModMapPath, "module.map");
435 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
436 parseModuleMapFile(ModMapFile);
437 inferred = InferredDirectories.find(ParentDir);
438 }
439
440 if (inferred == InferredDirectories.end())
441 inferred = InferredDirectories.insert(
442 std::make_pair(ParentDir, InferredDirectory())).first;
443 }
444
445 if (inferred->second.InferModules) {
446 // We're allowed to infer for this directory, but make sure it's okay
447 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000448 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000449 canInfer = std::find(inferred->second.ExcludedModules.begin(),
450 inferred->second.ExcludedModules.end(),
451 Name) == inferred->second.ExcludedModules.end();
452
453 if (inferred->second.InferSystemModules)
454 IsSystem = true;
455 }
456 }
457 }
458
459 // If we're not allowed to infer a framework module, don't.
460 if (!canInfer)
461 return 0;
462 }
463
464
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000465 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000466 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000467 llvm::sys::path::append(UmbrellaName, "Headers");
468 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000469 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000470
471 // FIXME: If there's no umbrella header, we could probably scan the
472 // framework to load *everything*. But, it's not clear that this is a good
473 // idea.
474 if (!UmbrellaHeader)
475 return 0;
476
Douglas Gregorac252a32011-12-06 19:39:29 +0000477 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
478 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000479 if (IsSystem)
480 Result->IsSystem = IsSystem;
481
Douglas Gregorb7a78192012-01-04 23:32:19 +0000482 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000483 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000484
Douglas Gregor489ad432011-12-08 18:00:48 +0000485 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000486 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000487 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000488 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000489
490 // export *
491 Result->Exports.push_back(Module::ExportDecl(0, true));
492
Douglas Gregore209e502011-12-06 01:10:29 +0000493 // module * { export * }
494 Result->InferSubmodules = true;
495 Result->InferExportWildcard = true;
496
Douglas Gregorac252a32011-12-06 19:39:29 +0000497 // Look for subframeworks.
498 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000499 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000500 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000501 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000502 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000503 llvm::sys::path::native(SubframeworksDirName.str(),
504 SubframeworksDirNameNative);
505 for (llvm::sys::fs::directory_iterator
506 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000507 Dir != DirEnd && !EC; Dir.increment(EC)) {
508 if (!StringRef(Dir->path()).endswith(".framework"))
509 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000510
Douglas Gregorac252a32011-12-06 19:39:29 +0000511 if (const DirectoryEntry *SubframeworkDir
512 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000513 // Note: as an egregious but useful hack, we use the real path here and
514 // check whether it is actually a subdirectory of the parent directory.
515 // This will not be the case if the 'subframework' is actually a symlink
516 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000517 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
518 bool FoundParent = false;
519 do {
520 // Get the parent directory name.
521 SubframeworkDirName
522 = llvm::sys::path::parent_path(SubframeworkDirName);
523 if (SubframeworkDirName.empty())
524 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000525
Douglas Gregor713b7c02013-01-26 00:55:12 +0000526 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
527 FoundParent = true;
528 break;
529 }
530 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000531
Douglas Gregor713b7c02013-01-26 00:55:12 +0000532 if (!FoundParent)
533 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000534
Douglas Gregorac252a32011-12-06 19:39:29 +0000535 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000536 SmallString<32> NameBuf;
537 inferFrameworkModule(sanitizeFilenameAsIdentifier(
538 llvm::sys::path::stem(Dir->path()), NameBuf),
539 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000540 }
541 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000542
Douglas Gregor8767dc22013-01-14 17:57:51 +0000543 // If the module is a top-level framework, automatically link against the
544 // framework.
545 if (!Result->isSubFramework()) {
546 inferFrameworkLink(Result, FrameworkDir, FileMgr);
547 }
548
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000549 return Result;
550}
551
Douglas Gregore209e502011-12-06 01:10:29 +0000552void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000553 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000554 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000555 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000556}
557
Douglas Gregor77d029f2011-12-08 19:11:24 +0000558void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
559 Mod->Umbrella = UmbrellaDir;
560 UmbrellaDirs[UmbrellaDir] = Mod;
561}
562
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000563void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
564 bool Excluded) {
565 if (Excluded)
566 Mod->ExcludedHeaders.push_back(Header);
567 else
568 Mod->Headers.push_back(Header);
569 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000570}
571
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000572const FileEntry *
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000573ModuleMap::getContainingModuleMapFile(Module *Module) {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000574 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
575 return 0;
576
577 return SourceMgr->getFileEntryForID(
578 SourceMgr->getFileID(Module->DefinitionLoc));
579}
580
Douglas Gregora30cfe52011-11-11 19:10:28 +0000581void ModuleMap::dump() {
582 llvm::errs() << "Modules:";
583 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
584 MEnd = Modules.end();
585 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000586 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000587
588 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000589 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000590 H != HEnd; ++H) {
591 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000592 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000593 }
594}
595
Douglas Gregor90db2602011-12-02 01:47:07 +0000596bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
597 bool HadError = false;
598 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
599 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
600 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000601 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000602 Mod->Exports.push_back(Export);
603 else
604 HadError = true;
605 }
606 Mod->UnresolvedExports.clear();
607 return HadError;
608}
609
Douglas Gregor55988682011-12-05 16:33:54 +0000610Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
611 if (Loc.isInvalid())
612 return 0;
613
614 // Use the expansion location to determine which module we're in.
615 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
616 if (!ExpansionLoc.isFileID())
617 return 0;
618
619
620 const SourceManager &SrcMgr = Loc.getManager();
621 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000622
Douglas Gregor303aae92012-01-06 17:19:32 +0000623 while (const FileEntry *ExpansionFile
624 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
625 // Find the module that owns this header (if any).
626 if (Module *Mod = findModuleForHeader(ExpansionFile))
627 return Mod;
628
629 // No module owns this header, so look up the inclusion chain to see if
630 // any included header has an associated module.
631 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
632 if (IncludeLoc.isInvalid())
633 return 0;
634
635 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
636 }
637
638 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000639}
640
Douglas Gregora30cfe52011-11-11 19:10:28 +0000641//----------------------------------------------------------------------------//
642// Module map file parser
643//----------------------------------------------------------------------------//
644
645namespace clang {
646 /// \brief A token in a module map file.
647 struct MMToken {
648 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000649 Comma,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000650 EndOfFile,
651 HeaderKeyword,
652 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000653 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000654 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000655 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000656 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000657 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000658 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000659 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000660 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000661 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000662 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000663 StringLiteral,
664 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000665 RBrace,
666 LSquare,
667 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000668 } Kind;
669
670 unsigned Location;
671 unsigned StringLength;
672 const char *StringData;
673
674 void clear() {
675 Kind = EndOfFile;
676 Location = 0;
677 StringLength = 0;
678 StringData = 0;
679 }
680
681 bool is(TokenKind K) const { return Kind == K; }
682
683 SourceLocation getLocation() const {
684 return SourceLocation::getFromRawEncoding(Location);
685 }
686
687 StringRef getString() const {
688 return StringRef(StringData, StringLength);
689 }
690 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000691
692 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000693 struct Attributes {
694 Attributes() : IsSystem() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000695
696 /// \brief Whether this is a system module.
697 unsigned IsSystem : 1;
698 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000699
Douglas Gregor82e52372012-11-06 19:39:40 +0000700
Douglas Gregora30cfe52011-11-11 19:10:28 +0000701 class ModuleMapParser {
702 Lexer &L;
703 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000704
705 /// \brief Default target information, used only for string literal
706 /// parsing.
707 const TargetInfo *Target;
708
Douglas Gregora30cfe52011-11-11 19:10:28 +0000709 DiagnosticsEngine &Diags;
710 ModuleMap &Map;
711
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000712 /// \brief The directory that this module map resides in.
713 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000714
715 /// \brief The directory containing Clang-supplied headers.
716 const DirectoryEntry *BuiltinIncludeDir;
717
Douglas Gregora30cfe52011-11-11 19:10:28 +0000718 /// \brief Whether an error occurred.
719 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000720
Douglas Gregora30cfe52011-11-11 19:10:28 +0000721 /// \brief Stores string data for the various string literals referenced
722 /// during parsing.
723 llvm::BumpPtrAllocator StringData;
724
725 /// \brief The current token.
726 MMToken Tok;
727
728 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000729 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000730
731 /// \brief Consume the current token and return its location.
732 SourceLocation consumeToken();
733
734 /// \brief Skip tokens until we reach the a token with the given kind
735 /// (or the end of the file).
736 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000737
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000738 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000739 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000740 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000741 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000742 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000743 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000744 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000745 void parseLinkDecl();
Douglas Gregor82e52372012-11-06 19:39:40 +0000746 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000747 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000748
Douglas Gregor6a1db482011-12-09 02:04:43 +0000749 const DirectoryEntry *getOverriddenHeaderSearchDir();
750
Douglas Gregora30cfe52011-11-11 19:10:28 +0000751 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000752 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000753 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000754 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000755 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000756 const DirectoryEntry *Directory,
757 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000758 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000759 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
760 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000761 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000762 Tok.clear();
763 consumeToken();
764 }
765
766 bool parseModuleMapFile();
767 };
768}
769
770SourceLocation ModuleMapParser::consumeToken() {
771retry:
772 SourceLocation Result = Tok.getLocation();
773 Tok.clear();
774
775 Token LToken;
776 L.LexFromRawLexer(LToken);
777 Tok.Location = LToken.getLocation().getRawEncoding();
778 switch (LToken.getKind()) {
779 case tok::raw_identifier:
780 Tok.StringData = LToken.getRawIdentifierData();
781 Tok.StringLength = LToken.getLength();
782 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
783 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000784 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000785 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000786 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000787 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000788 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000789 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000790 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000791 .Case("umbrella", MMToken::UmbrellaKeyword)
792 .Default(MMToken::Identifier);
793 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000794
795 case tok::comma:
796 Tok.Kind = MMToken::Comma;
797 break;
798
Douglas Gregora30cfe52011-11-11 19:10:28 +0000799 case tok::eof:
800 Tok.Kind = MMToken::EndOfFile;
801 break;
802
803 case tok::l_brace:
804 Tok.Kind = MMToken::LBrace;
805 break;
806
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000807 case tok::l_square:
808 Tok.Kind = MMToken::LSquare;
809 break;
810
Douglas Gregor90db2602011-12-02 01:47:07 +0000811 case tok::period:
812 Tok.Kind = MMToken::Period;
813 break;
814
Douglas Gregora30cfe52011-11-11 19:10:28 +0000815 case tok::r_brace:
816 Tok.Kind = MMToken::RBrace;
817 break;
818
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000819 case tok::r_square:
820 Tok.Kind = MMToken::RSquare;
821 break;
822
Douglas Gregor90db2602011-12-02 01:47:07 +0000823 case tok::star:
824 Tok.Kind = MMToken::Star;
825 break;
826
Douglas Gregora30cfe52011-11-11 19:10:28 +0000827 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000828 if (LToken.hasUDSuffix()) {
829 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
830 HadError = true;
831 goto retry;
832 }
833
Douglas Gregora30cfe52011-11-11 19:10:28 +0000834 // Parse the string literal.
835 LangOptions LangOpts;
836 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
837 if (StringLiteral.hadError)
838 goto retry;
839
840 // Copy the string literal into our string data allocator.
841 unsigned Length = StringLiteral.GetStringLength();
842 char *Saved = StringData.Allocate<char>(Length + 1);
843 memcpy(Saved, StringLiteral.GetString().data(), Length);
844 Saved[Length] = 0;
845
846 // Form the token.
847 Tok.Kind = MMToken::StringLiteral;
848 Tok.StringData = Saved;
849 Tok.StringLength = Length;
850 break;
851 }
852
853 case tok::comment:
854 goto retry;
855
856 default:
857 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
858 HadError = true;
859 goto retry;
860 }
861
862 return Result;
863}
864
865void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
866 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000867 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000868 do {
869 switch (Tok.Kind) {
870 case MMToken::EndOfFile:
871 return;
872
873 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000874 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000875 return;
876
877 ++braceDepth;
878 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000879
880 case MMToken::LSquare:
881 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
882 return;
883
884 ++squareDepth;
885 break;
886
Douglas Gregora30cfe52011-11-11 19:10:28 +0000887 case MMToken::RBrace:
888 if (braceDepth > 0)
889 --braceDepth;
890 else if (Tok.is(K))
891 return;
892 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000893
894 case MMToken::RSquare:
895 if (squareDepth > 0)
896 --squareDepth;
897 else if (Tok.is(K))
898 return;
899 break;
900
Douglas Gregora30cfe52011-11-11 19:10:28 +0000901 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000902 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000903 return;
904 break;
905 }
906
907 consumeToken();
908 } while (true);
909}
910
Douglas Gregor587986e2011-12-07 02:23:45 +0000911/// \brief Parse a module-id.
912///
913/// module-id:
914/// identifier
915/// identifier '.' module-id
916///
917/// \returns true if an error occurred, false otherwise.
918bool ModuleMapParser::parseModuleId(ModuleId &Id) {
919 Id.clear();
920 do {
921 if (Tok.is(MMToken::Identifier)) {
922 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
923 consumeToken();
924 } else {
925 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
926 return true;
927 }
928
929 if (!Tok.is(MMToken::Period))
930 break;
931
932 consumeToken();
933 } while (true);
934
935 return false;
936}
937
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000938namespace {
939 /// \brief Enumerates the known attributes.
940 enum AttributeKind {
941 /// \brief An unknown attribute.
942 AT_unknown,
943 /// \brief The 'system' attribute.
944 AT_system
945 };
946}
947
Douglas Gregora30cfe52011-11-11 19:10:28 +0000948/// \brief Parse a module declaration.
949///
950/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000951/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
952/// { module-member* }
953///
Douglas Gregora30cfe52011-11-11 19:10:28 +0000954/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +0000955/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000956/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +0000957/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +0000958/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000959/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +0000960///
961/// submodule-declaration:
962/// module-declaration
963/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000964void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +0000965 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
966 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +0000967 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +0000968 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000969 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +0000970 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +0000971
Douglas Gregord620a842011-12-06 17:16:41 +0000972 // Parse 'explicit' keyword, if present.
973 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +0000974 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +0000975 Explicit = true;
976 }
977
978 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +0000979 if (Tok.is(MMToken::FrameworkKeyword)) {
980 consumeToken();
981 Framework = true;
982 }
Douglas Gregora30cfe52011-11-11 19:10:28 +0000983
984 // Parse 'module' keyword.
985 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +0000986 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000987 consumeToken();
988 HadError = true;
989 return;
990 }
991 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +0000992
993 // If we have a wildcard for the module name, this is an inferred submodule.
994 // Parse it.
995 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +0000996 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000997
998 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +0000999 ModuleId Id;
1000 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001001 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001002 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001003 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001004
Douglas Gregor587986e2011-12-07 02:23:45 +00001005 if (ActiveModule) {
1006 if (Id.size() > 1) {
1007 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1008 << SourceRange(Id.front().second, Id.back().second);
1009
1010 HadError = true;
1011 return;
1012 }
1013 } else if (Id.size() == 1 && Explicit) {
1014 // Top-level modules can't be explicit.
1015 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1016 Explicit = false;
1017 ExplicitLoc = SourceLocation();
1018 HadError = true;
1019 }
1020
1021 Module *PreviousActiveModule = ActiveModule;
1022 if (Id.size() > 1) {
1023 // This module map defines a submodule. Go find the module of which it
1024 // is a submodule.
1025 ActiveModule = 0;
1026 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1027 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1028 ActiveModule = Next;
1029 continue;
1030 }
1031
1032 if (ActiveModule) {
1033 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1034 << Id[I].first << ActiveModule->getTopLevelModule();
1035 } else {
1036 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1037 }
1038 HadError = true;
1039 return;
1040 }
1041 }
1042
1043 StringRef ModuleName = Id.back().first;
1044 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001045
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001046 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001047 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001048 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001049
Douglas Gregora30cfe52011-11-11 19:10:28 +00001050 // Parse the opening brace.
1051 if (!Tok.is(MMToken::LBrace)) {
1052 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1053 << ModuleName;
1054 HadError = true;
1055 return;
1056 }
1057 SourceLocation LBraceLoc = consumeToken();
1058
1059 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001060 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001061 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1062 // Skip the module definition.
1063 skipUntil(MMToken::RBrace);
1064 if (Tok.is(MMToken::RBrace))
1065 consumeToken();
1066 else {
1067 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1068 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1069 HadError = true;
1070 }
1071 return;
1072 }
1073
Douglas Gregora30cfe52011-11-11 19:10:28 +00001074 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1075 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001076 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001077
1078 // Skip the module definition.
1079 skipUntil(MMToken::RBrace);
1080 if (Tok.is(MMToken::RBrace))
1081 consumeToken();
1082
1083 HadError = true;
1084 return;
1085 }
1086
1087 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001088 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1089 Explicit).first;
1090 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001091 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001092 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001093
1094 bool Done = false;
1095 do {
1096 switch (Tok.Kind) {
1097 case MMToken::EndOfFile:
1098 case MMToken::RBrace:
1099 Done = true;
1100 break;
1101
1102 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001103 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001104 case MMToken::ModuleKeyword:
1105 parseModuleDecl();
1106 break;
1107
Douglas Gregor90db2602011-12-02 01:47:07 +00001108 case MMToken::ExportKeyword:
1109 parseExportDecl();
1110 break;
1111
Douglas Gregor51f564f2011-12-31 04:05:44 +00001112 case MMToken::RequiresKeyword:
1113 parseRequiresDecl();
1114 break;
1115
Douglas Gregor77d029f2011-12-08 19:11:24 +00001116 case MMToken::UmbrellaKeyword: {
1117 SourceLocation UmbrellaLoc = consumeToken();
1118 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001119 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001120 else
1121 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001122 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001123 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001124
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001125 case MMToken::ExcludeKeyword: {
1126 SourceLocation ExcludeLoc = consumeToken();
1127 if (Tok.is(MMToken::HeaderKeyword)) {
1128 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1129 } else {
1130 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1131 << "exclude";
1132 }
1133 break;
1134 }
1135
Douglas Gregor489ad432011-12-08 18:00:48 +00001136 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001137 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001138 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001139
1140 case MMToken::LinkKeyword:
1141 parseLinkDecl();
1142 break;
1143
Douglas Gregora30cfe52011-11-11 19:10:28 +00001144 default:
1145 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1146 consumeToken();
1147 break;
1148 }
1149 } while (!Done);
1150
1151 if (Tok.is(MMToken::RBrace))
1152 consumeToken();
1153 else {
1154 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1155 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1156 HadError = true;
1157 }
1158
Douglas Gregor8767dc22013-01-14 17:57:51 +00001159 // If the active module is a top-level framework, and there are no link
1160 // libraries, automatically link against the framework.
1161 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1162 ActiveModule->LinkLibraries.empty()) {
1163 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1164 }
1165
Douglas Gregor587986e2011-12-07 02:23:45 +00001166 // We're done parsing this module. Pop back to the previous module.
1167 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001168}
Douglas Gregord620a842011-12-06 17:16:41 +00001169
Douglas Gregor51f564f2011-12-31 04:05:44 +00001170/// \brief Parse a requires declaration.
1171///
1172/// requires-declaration:
1173/// 'requires' feature-list
1174///
1175/// feature-list:
1176/// identifier ',' feature-list
1177/// identifier
1178void ModuleMapParser::parseRequiresDecl() {
1179 assert(Tok.is(MMToken::RequiresKeyword));
1180
1181 // Parse 'requires' keyword.
1182 consumeToken();
1183
1184 // Parse the feature-list.
1185 do {
1186 if (!Tok.is(MMToken::Identifier)) {
1187 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1188 HadError = true;
1189 return;
1190 }
1191
1192 // Consume the feature name.
1193 std::string Feature = Tok.getString();
1194 consumeToken();
1195
1196 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001197 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001198
1199 if (!Tok.is(MMToken::Comma))
1200 break;
1201
1202 // Consume the comma.
1203 consumeToken();
1204 } while (true);
1205}
1206
Douglas Gregord620a842011-12-06 17:16:41 +00001207/// \brief Append to \p Paths the set of paths needed to get to the
1208/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001209static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001210 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001211 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001212 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001213 for (; Mod; Mod = Mod->Parent) {
1214 if (Mod->IsFramework)
1215 Paths.push_back(Mod->Name);
1216 }
1217
1218 if (Paths.empty())
1219 return;
1220
1221 // Add Frameworks/Name.framework for each subframework.
1222 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1223 llvm::sys::path::append(Path, "Frameworks");
1224 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1225 }
1226}
1227
Douglas Gregor2f04f182012-02-02 18:42:48 +00001228/// \brief Determine whether the given file name is the name of a builtin
1229/// header, supplied by Clang to replace, override, or augment existing system
1230/// headers.
1231static bool isBuiltinHeader(StringRef FileName) {
1232 return llvm::StringSwitch<bool>(FileName)
1233 .Case("float.h", true)
1234 .Case("iso646.h", true)
1235 .Case("limits.h", true)
1236 .Case("stdalign.h", true)
1237 .Case("stdarg.h", true)
1238 .Case("stdbool.h", true)
1239 .Case("stddef.h", true)
1240 .Case("stdint.h", true)
1241 .Case("tgmath.h", true)
1242 .Case("unwind.h", true)
1243 .Default(false);
1244}
1245
Douglas Gregora30cfe52011-11-11 19:10:28 +00001246/// \brief Parse a header declaration.
1247///
1248/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001249/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001250/// 'exclude'[opt] 'header' string-literal
1251void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1252 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001253 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001254 consumeToken();
1255
Douglas Gregor489ad432011-12-08 18:00:48 +00001256 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001257 bool Exclude = ExcludeLoc.isValid();
1258 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001259 // Parse the header name.
1260 if (!Tok.is(MMToken::StringLiteral)) {
1261 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1262 << "header";
1263 HadError = true;
1264 return;
1265 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001266 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001267 SourceLocation FileNameLoc = consumeToken();
1268
Douglas Gregor77d029f2011-12-08 19:11:24 +00001269 // Check whether we already have an umbrella.
1270 if (Umbrella && ActiveModule->Umbrella) {
1271 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1272 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001273 HadError = true;
1274 return;
1275 }
1276
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001277 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001278 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001279 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001280 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001281 if (llvm::sys::path::is_absolute(FileName)) {
1282 PathName = FileName;
1283 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001284 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1285 PathName = Dir->getName();
1286 llvm::sys::path::append(PathName, FileName);
1287 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001288 } else {
1289 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001290 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001291 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001292
Douglas Gregord620a842011-12-06 17:16:41 +00001293 if (ActiveModule->isPartOfFramework()) {
1294 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001295
1296 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001297 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001298 llvm::sys::path::append(PathName, FileName);
1299 File = SourceMgr.getFileManager().getFile(PathName);
1300
1301 if (!File) {
1302 // Check whether this file is in the private headers.
1303 PathName.resize(PathLength);
1304 llvm::sys::path::append(PathName, "PrivateHeaders");
1305 llvm::sys::path::append(PathName, FileName);
1306 File = SourceMgr.getFileManager().getFile(PathName);
1307 }
1308 } else {
1309 // Lookup for normal headers.
1310 llvm::sys::path::append(PathName, FileName);
1311 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001312
1313 // If this is a system module with a top-level header, this header
1314 // may have a counterpart (or replacement) in the set of headers
1315 // supplied by Clang. Find that builtin header.
1316 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1317 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001318 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001319 llvm::sys::path::append(BuiltinPathName, FileName);
1320 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1321
1322 // If Clang supplies this header but the underlying system does not,
1323 // just silently swap in our builtin version. Otherwise, we'll end
1324 // up adding both (later).
1325 if (!File && BuiltinFile) {
1326 File = BuiltinFile;
1327 BuiltinFile = 0;
1328 }
1329 }
Douglas Gregord620a842011-12-06 17:16:41 +00001330 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001331 }
Douglas Gregora8654052011-11-17 22:09:43 +00001332
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001333 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1334 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001335 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001336 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001337 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001338 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001339 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001340 } else if (Umbrella) {
1341 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001342 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001343 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001344 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001345 HadError = true;
1346 } else {
1347 // Record this umbrella header.
1348 Map.setUmbrellaHeader(ActiveModule, File);
1349 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001350 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001351 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001352 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001353
1354 // If there is a builtin counterpart to this file, add it now.
1355 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001356 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001357 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001358 } else if (!Exclude) {
1359 // Ignore excluded header files. They're optional anyway.
1360
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001361 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001362 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001363 HadError = true;
1364 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001365}
1366
Douglas Gregor77d029f2011-12-08 19:11:24 +00001367/// \brief Parse an umbrella directory declaration.
1368///
1369/// umbrella-dir-declaration:
1370/// umbrella string-literal
1371void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1372 // Parse the directory name.
1373 if (!Tok.is(MMToken::StringLiteral)) {
1374 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1375 << "umbrella";
1376 HadError = true;
1377 return;
1378 }
1379
1380 std::string DirName = Tok.getString();
1381 SourceLocation DirNameLoc = consumeToken();
1382
1383 // Check whether we already have an umbrella.
1384 if (ActiveModule->Umbrella) {
1385 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1386 << ActiveModule->getFullModuleName();
1387 HadError = true;
1388 return;
1389 }
1390
1391 // Look for this file.
1392 const DirectoryEntry *Dir = 0;
1393 if (llvm::sys::path::is_absolute(DirName))
1394 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1395 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001396 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001397 PathName = Directory->getName();
1398 llvm::sys::path::append(PathName, DirName);
1399 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1400 }
1401
1402 if (!Dir) {
1403 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1404 << DirName;
1405 HadError = true;
1406 return;
1407 }
1408
1409 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1410 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1411 << OwningModule->getFullModuleName();
1412 HadError = true;
1413 return;
1414 }
1415
1416 // Record this umbrella directory.
1417 Map.setUmbrellaDir(ActiveModule, Dir);
1418}
1419
Douglas Gregor90db2602011-12-02 01:47:07 +00001420/// \brief Parse a module export declaration.
1421///
1422/// export-declaration:
1423/// 'export' wildcard-module-id
1424///
1425/// wildcard-module-id:
1426/// identifier
1427/// '*'
1428/// identifier '.' wildcard-module-id
1429void ModuleMapParser::parseExportDecl() {
1430 assert(Tok.is(MMToken::ExportKeyword));
1431 SourceLocation ExportLoc = consumeToken();
1432
1433 // Parse the module-id with an optional wildcard at the end.
1434 ModuleId ParsedModuleId;
1435 bool Wildcard = false;
1436 do {
1437 if (Tok.is(MMToken::Identifier)) {
1438 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1439 Tok.getLocation()));
1440 consumeToken();
1441
1442 if (Tok.is(MMToken::Period)) {
1443 consumeToken();
1444 continue;
1445 }
1446
1447 break;
1448 }
1449
1450 if(Tok.is(MMToken::Star)) {
1451 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001452 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001453 break;
1454 }
1455
1456 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1457 HadError = true;
1458 return;
1459 } while (true);
1460
1461 Module::UnresolvedExportDecl Unresolved = {
1462 ExportLoc, ParsedModuleId, Wildcard
1463 };
1464 ActiveModule->UnresolvedExports.push_back(Unresolved);
1465}
1466
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001467/// \brief Parse a link declaration.
1468///
1469/// module-declaration:
1470/// 'link' 'framework'[opt] string-literal
1471void ModuleMapParser::parseLinkDecl() {
1472 assert(Tok.is(MMToken::LinkKeyword));
1473 SourceLocation LinkLoc = consumeToken();
1474
1475 // Parse the optional 'framework' keyword.
1476 bool IsFramework = false;
1477 if (Tok.is(MMToken::FrameworkKeyword)) {
1478 consumeToken();
1479 IsFramework = true;
1480 }
1481
1482 // Parse the library name
1483 if (!Tok.is(MMToken::StringLiteral)) {
1484 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1485 << IsFramework << SourceRange(LinkLoc);
1486 HadError = true;
1487 return;
1488 }
1489
1490 std::string LibraryName = Tok.getString();
1491 consumeToken();
1492 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1493 IsFramework));
1494}
1495
1496/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001497///
1498/// module-declaration:
1499/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1500/// { inferred-module-member* }
1501///
1502/// inferred-module-member:
1503/// 'export' '*'
1504/// 'exclude' identifier
1505void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001506 assert(Tok.is(MMToken::Star));
1507 SourceLocation StarLoc = consumeToken();
1508 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001509
Douglas Gregor1e123682011-12-05 22:27:44 +00001510 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001511 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001512 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1513 Failed = true;
1514 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001515
1516 if (ActiveModule) {
1517 // Inferred modules must have umbrella directories.
1518 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1519 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1520 Failed = true;
1521 }
1522
1523 // Check for redefinition of an inferred module.
1524 if (!Failed && ActiveModule->InferSubmodules) {
1525 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1526 if (ActiveModule->InferredSubmoduleLoc.isValid())
1527 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1528 diag::note_mmap_prev_definition);
1529 Failed = true;
1530 }
1531
1532 // Check for the 'framework' keyword, which is not permitted here.
1533 if (Framework) {
1534 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1535 Framework = false;
1536 }
1537 } else if (Explicit) {
1538 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1539 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001540 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001541
Douglas Gregor1e123682011-12-05 22:27:44 +00001542 // If there were any problems with this inferred submodule, skip its body.
1543 if (Failed) {
1544 if (Tok.is(MMToken::LBrace)) {
1545 consumeToken();
1546 skipUntil(MMToken::RBrace);
1547 if (Tok.is(MMToken::RBrace))
1548 consumeToken();
1549 }
1550 HadError = true;
1551 return;
1552 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001553
1554 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001555 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001556 parseOptionalAttributes(Attrs);
1557
1558 if (ActiveModule) {
1559 // Note that we have an inferred submodule.
1560 ActiveModule->InferSubmodules = true;
1561 ActiveModule->InferredSubmoduleLoc = StarLoc;
1562 ActiveModule->InferExplicitSubmodules = Explicit;
1563 } else {
1564 // We'll be inferring framework modules for this directory.
1565 Map.InferredDirectories[Directory].InferModules = true;
1566 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1567 }
1568
Douglas Gregor1e123682011-12-05 22:27:44 +00001569 // Parse the opening brace.
1570 if (!Tok.is(MMToken::LBrace)) {
1571 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1572 HadError = true;
1573 return;
1574 }
1575 SourceLocation LBraceLoc = consumeToken();
1576
1577 // Parse the body of the inferred submodule.
1578 bool Done = false;
1579 do {
1580 switch (Tok.Kind) {
1581 case MMToken::EndOfFile:
1582 case MMToken::RBrace:
1583 Done = true;
1584 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001585
1586 case MMToken::ExcludeKeyword: {
1587 if (ActiveModule) {
1588 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001589 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001590 consumeToken();
1591 break;
1592 }
1593
1594 consumeToken();
1595 if (!Tok.is(MMToken::Identifier)) {
1596 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1597 break;
1598 }
1599
1600 Map.InferredDirectories[Directory].ExcludedModules
1601 .push_back(Tok.getString());
1602 consumeToken();
1603 break;
1604 }
1605
1606 case MMToken::ExportKeyword:
1607 if (!ActiveModule) {
1608 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001609 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001610 consumeToken();
1611 break;
1612 }
1613
Douglas Gregor1e123682011-12-05 22:27:44 +00001614 consumeToken();
1615 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001616 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001617 else
1618 Diags.Report(Tok.getLocation(),
1619 diag::err_mmap_expected_export_wildcard);
1620 consumeToken();
1621 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001622
Douglas Gregor1e123682011-12-05 22:27:44 +00001623 case MMToken::ExplicitKeyword:
1624 case MMToken::ModuleKeyword:
1625 case MMToken::HeaderKeyword:
1626 case MMToken::UmbrellaKeyword:
1627 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001628 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001629 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001630 consumeToken();
1631 break;
1632 }
1633 } while (!Done);
1634
1635 if (Tok.is(MMToken::RBrace))
1636 consumeToken();
1637 else {
1638 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1639 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1640 HadError = true;
1641 }
1642}
1643
Douglas Gregor82e52372012-11-06 19:39:40 +00001644/// \brief Parse optional attributes.
1645///
1646/// attributes:
1647/// attribute attributes
1648/// attribute
1649///
1650/// attribute:
1651/// [ identifier ]
1652///
1653/// \param Attrs Will be filled in with the parsed attributes.
1654///
1655/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001656bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001657 bool HadError = false;
1658
1659 while (Tok.is(MMToken::LSquare)) {
1660 // Consume the '['.
1661 SourceLocation LSquareLoc = consumeToken();
1662
1663 // Check whether we have an attribute name here.
1664 if (!Tok.is(MMToken::Identifier)) {
1665 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1666 skipUntil(MMToken::RSquare);
1667 if (Tok.is(MMToken::RSquare))
1668 consumeToken();
1669 HadError = true;
1670 }
1671
1672 // Decode the attribute name.
1673 AttributeKind Attribute
1674 = llvm::StringSwitch<AttributeKind>(Tok.getString())
1675 .Case("system", AT_system)
1676 .Default(AT_unknown);
1677 switch (Attribute) {
1678 case AT_unknown:
1679 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1680 << Tok.getString();
1681 break;
1682
1683 case AT_system:
1684 Attrs.IsSystem = true;
1685 break;
1686 }
1687 consumeToken();
1688
1689 // Consume the ']'.
1690 if (!Tok.is(MMToken::RSquare)) {
1691 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1692 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1693 skipUntil(MMToken::RSquare);
1694 HadError = true;
1695 }
1696
1697 if (Tok.is(MMToken::RSquare))
1698 consumeToken();
1699 }
1700
1701 return HadError;
1702}
1703
Douglas Gregor6a1db482011-12-09 02:04:43 +00001704/// \brief If there is a specific header search directory due the presence
1705/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1706const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1707 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1708 // If we have an umbrella directory, use that.
1709 if (Mod->hasUmbrellaDir())
1710 return Mod->getUmbrellaDir();
1711
1712 // If we have a framework directory, stop looking.
1713 if (Mod->IsFramework)
1714 return 0;
1715 }
1716
1717 return 0;
1718}
1719
Douglas Gregora30cfe52011-11-11 19:10:28 +00001720/// \brief Parse a module map file.
1721///
1722/// module-map-file:
1723/// module-declaration*
1724bool ModuleMapParser::parseModuleMapFile() {
1725 do {
1726 switch (Tok.Kind) {
1727 case MMToken::EndOfFile:
1728 return HadError;
1729
Douglas Gregor587986e2011-12-07 02:23:45 +00001730 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001731 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001732 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001733 parseModuleDecl();
1734 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001735
Douglas Gregor51f564f2011-12-31 04:05:44 +00001736 case MMToken::Comma:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001737 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001738 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001739 case MMToken::HeaderKeyword:
1740 case MMToken::Identifier:
1741 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001742 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001743 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001744 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001745 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001746 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001747 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001748 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001749 case MMToken::StringLiteral:
1750 case MMToken::UmbrellaKeyword:
1751 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1752 HadError = true;
1753 consumeToken();
1754 break;
1755 }
1756 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001757}
1758
1759bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001760 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1761 = ParsedModuleMap.find(File);
1762 if (Known != ParsedModuleMap.end())
1763 return Known->second;
1764
Douglas Gregordc58aa72012-01-30 06:01:29 +00001765 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001766 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1767 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1768 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001769 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001770
1771 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001772 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1773 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001774 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001775 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001776 bool Result = Parser.parseModuleMapFile();
1777 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001778 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001779 return Result;
1780}