blob: d411ead7e96527c03ddde0cd377a7a20009c9451 [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"
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000021#include "clang/Lex/HeaderSearch.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000022#include "clang/Lex/LexDiagnostic.h"
23#include "clang/Lex/Lexer.h"
24#include "clang/Lex/LiteralSupport.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/ADT/StringSwitch.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000027#include "llvm/Support/Allocator.h"
Douglas Gregorac252a32011-12-06 19:39:29 +000028#include "llvm/Support/FileSystem.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000029#include "llvm/Support/Host.h"
Rafael Espindola8229d222013-06-11 22:15:02 +000030#include "llvm/Support/Path.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000031#include "llvm/Support/raw_ostream.h"
Douglas Gregor98cfcbf2012-09-27 14:50:15 +000032#include <stdlib.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000033#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoadeb7822013-01-26 16:29:36 +000034#include <limits.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000035#endif
Douglas Gregora30cfe52011-11-11 19:10:28 +000036using namespace clang;
37
Douglas Gregor90db2602011-12-02 01:47:07 +000038Module::ExportDecl
39ModuleMap::resolveExport(Module *Mod,
40 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +000041 bool Complain) const {
Douglas Gregor0adaa882011-12-05 17:28:06 +000042 // We may have just a wildcard.
43 if (Unresolved.Id.empty()) {
44 assert(Unresolved.Wildcard && "Invalid unresolved export");
45 return Module::ExportDecl(0, true);
46 }
47
Douglas Gregor906d66a2013-03-20 21:10:35 +000048 // Resolve the module-id.
49 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
50 if (!Context)
51 return Module::ExportDecl();
52
53 return Module::ExportDecl(Context, Unresolved.Wildcard);
54}
55
56Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
57 bool Complain) const {
Douglas Gregor90db2602011-12-02 01:47:07 +000058 // Find the starting module.
Douglas Gregor906d66a2013-03-20 21:10:35 +000059 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor90db2602011-12-02 01:47:07 +000060 if (!Context) {
61 if (Complain)
Douglas Gregor906d66a2013-03-20 21:10:35 +000062 Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
63 << Id[0].first << Mod->getFullModuleName();
64
65 return 0;
Douglas Gregor90db2602011-12-02 01:47:07 +000066 }
67
68 // Dig into the module path.
Douglas Gregor906d66a2013-03-20 21:10:35 +000069 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
70 Module *Sub = lookupModuleQualified(Id[I].first, Context);
Douglas Gregor90db2602011-12-02 01:47:07 +000071 if (!Sub) {
72 if (Complain)
Douglas Gregor906d66a2013-03-20 21:10:35 +000073 Diags->Report(Id[I].second, diag::err_mmap_missing_module_qualified)
74 << Id[I].first << Context->getFullModuleName()
75 << SourceRange(Id[0].second, Id[I-1].second);
76
77 return 0;
Douglas Gregor90db2602011-12-02 01:47:07 +000078 }
Douglas Gregor906d66a2013-03-20 21:10:35 +000079
Douglas Gregor90db2602011-12-02 01:47:07 +000080 Context = Sub;
81 }
Douglas Gregor906d66a2013-03-20 21:10:35 +000082
83 return Context;
Douglas Gregor90db2602011-12-02 01:47:07 +000084}
85
Douglas Gregora4a90ca2013-05-03 22:58:43 +000086ModuleMap::ModuleMap(FileManager &FileMgr, DiagnosticConsumer &DC,
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000087 const LangOptions &LangOpts, const TargetInfo *Target,
88 HeaderSearch &HeaderInfo)
89 : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +000090 BuiltinIncludeDir(0), CompilingModule(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000091{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000092 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
93 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000094 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora4a90ca2013-05-03 22:58:43 +000095 Diags->setClient(new ForwardingDiagnosticConsumer(DC),
96 /*ShouldOwnClient=*/true);
Douglas Gregora30cfe52011-11-11 19:10:28 +000097 SourceMgr = new SourceManager(*Diags, FileMgr);
98}
99
100ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +0000101 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
102 IEnd = Modules.end();
103 I != IEnd; ++I) {
104 delete I->getValue();
105 }
106
Douglas Gregora30cfe52011-11-11 19:10:28 +0000107 delete SourceMgr;
108}
109
Douglas Gregordc58aa72012-01-30 06:01:29 +0000110void ModuleMap::setTarget(const TargetInfo &Target) {
111 assert((!this->Target || this->Target == &Target) &&
112 "Improper target override");
113 this->Target = &Target;
114}
115
Douglas Gregor8b48e082012-10-12 21:15:50 +0000116/// \brief "Sanitize" a filename so that it can be used as an identifier.
117static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
118 SmallVectorImpl<char> &Buffer) {
119 if (Name.empty())
120 return Name;
121
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000122 if (!isValidIdentifier(Name)) {
Douglas Gregor8b48e082012-10-12 21:15:50 +0000123 // If we don't already have something with the form of an identifier,
124 // create a buffer with the sanitized name.
125 Buffer.clear();
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000126 if (isDigit(Name[0]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000127 Buffer.push_back('_');
128 Buffer.reserve(Buffer.size() + Name.size());
129 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000130 if (isIdentifierBody(Name[I]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000131 Buffer.push_back(Name[I]);
132 else
133 Buffer.push_back('_');
134 }
135
136 Name = StringRef(Buffer.data(), Buffer.size());
137 }
138
139 while (llvm::StringSwitch<bool>(Name)
140#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
141#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
142#include "clang/Basic/TokenKinds.def"
143 .Default(false)) {
144 if (Name.data() != Buffer.data())
145 Buffer.append(Name.begin(), Name.end());
146 Buffer.push_back('_');
147 Name = StringRef(Buffer.data(), Buffer.size());
148 }
149
150 return Name;
151}
152
Douglas Gregordb3910b2013-05-02 17:58:30 +0000153/// \brief Determine whether the given file name is the name of a builtin
154/// header, supplied by Clang to replace, override, or augment existing system
155/// headers.
156static bool isBuiltinHeader(StringRef FileName) {
157 return llvm::StringSwitch<bool>(FileName)
158 .Case("float.h", true)
159 .Case("iso646.h", true)
160 .Case("limits.h", true)
161 .Case("stdalign.h", true)
162 .Case("stdarg.h", true)
163 .Case("stdbool.h", true)
164 .Case("stddef.h", true)
165 .Case("stdint.h", true)
166 .Case("tgmath.h", true)
167 .Case("unwind.h", true)
168 .Default(false);
169}
170
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000171ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000172 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000173 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000174 // If a header is not available, don't report that it maps to anything.
175 if (!Known->second.isAvailable())
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000176 return KnownHeader();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000177
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000178 return Known->second;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000179 }
Douglas Gregordb3910b2013-05-02 17:58:30 +0000180
181 // If we've found a builtin header within Clang's builtin include directory,
182 // load all of the module maps to see if it will get associated with a
183 // specific module (e.g., in /usr/include).
184 if (File->getDir() == BuiltinIncludeDir &&
185 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
Douglas Gregor30a16f12013-05-10 22:52:27 +0000186 HeaderInfo.loadTopLevelSystemModules();
Douglas Gregordb3910b2013-05-02 17:58:30 +0000187
188 // Check again.
189 Known = Headers.find(File);
190 if (Known != Headers.end()) {
191 // If a header is not available, don't report that it maps to anything.
192 if (!Known->second.isAvailable())
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000193 return KnownHeader();
Douglas Gregordb3910b2013-05-02 17:58:30 +0000194
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000195 return Known->second;
Douglas Gregordb3910b2013-05-02 17:58:30 +0000196 }
197 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000198
Douglas Gregoradb97992011-11-16 23:02:25 +0000199 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000200 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000201
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000202 // Note: as an egregious but useful hack we use the real path here, because
203 // frameworks moving from top-level frameworks to embedded frameworks tend
204 // to be symlinked from the top-level location to the embedded location,
205 // and we need to resolve lookups as if we had found the embedded location.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000206 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000207
208 // Keep walking up the directory hierarchy, looking for a directory with
209 // an umbrella header.
210 do {
211 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
212 = UmbrellaDirs.find(Dir);
213 if (KnownDir != UmbrellaDirs.end()) {
214 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000215
216 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000217 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000218 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000219 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000220 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000221
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000222 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000223 // Infer submodules for each of the directories we found between
224 // the directory of the umbrella header and the directory where
225 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000226 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000227
Douglas Gregor6a1db482011-12-09 02:04:43 +0000228 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000229 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000230 SmallString<32> NameBuf;
231 StringRef Name = sanitizeFilenameAsIdentifier(
232 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
233 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000234 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000235 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000236
237 // Associate the module and the directory.
238 UmbrellaDirs[SkippedDirs[I-1]] = Result;
239
240 // If inferred submodules export everything they import, add a
241 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000242 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000243 Result->Exports.push_back(Module::ExportDecl(0, true));
244 }
245
246 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000247 SmallString<32> NameBuf;
248 StringRef Name = sanitizeFilenameAsIdentifier(
249 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000250 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000251 Explicit).first;
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +0000252 Result->addTopHeader(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000253
254 // If inferred submodules export everything they import, add a
255 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000256 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000257 Result->Exports.push_back(Module::ExportDecl(0, true));
258 } else {
259 // Record each of the directories we stepped through as being part of
260 // the module we found, since the umbrella header covers them all.
261 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
262 UmbrellaDirs[SkippedDirs[I]] = Result;
263 }
264
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000265 Headers[File] = KnownHeader(Result, NormalHeader);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000266
267 // If a header corresponds to an unavailable module, don't report
268 // that it maps to anything.
269 if (!Result->isAvailable())
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000270 return KnownHeader();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000271
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000272 return Headers[File];
Douglas Gregore209e502011-12-06 01:10:29 +0000273 }
274
275 SkippedDirs.push_back(Dir);
276
Douglas Gregoradb97992011-11-16 23:02:25 +0000277 // Retrieve our parent path.
278 DirName = llvm::sys::path::parent_path(DirName);
279 if (DirName.empty())
280 break;
281
282 // Resolve the parent path to a directory entry.
283 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000284 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000285
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000286 return KnownHeader();
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000287}
288
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000289bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
290 HeadersMap::const_iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000291 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000292 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000293
294 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000295 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000296 StringRef DirName = Dir->getName();
297
298 // Keep walking up the directory hierarchy, looking for a directory with
299 // an umbrella header.
300 do {
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000301 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor51f564f2011-12-31 04:05:44 +0000302 = UmbrellaDirs.find(Dir);
303 if (KnownDir != UmbrellaDirs.end()) {
304 Module *Found = KnownDir->second;
305 if (!Found->isAvailable())
306 return true;
307
308 // Search up the module stack until we find a module with an umbrella
309 // directory.
310 Module *UmbrellaModule = Found;
311 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
312 UmbrellaModule = UmbrellaModule->Parent;
313
314 if (UmbrellaModule->InferSubmodules) {
315 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
316 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000317 SmallString<32> NameBuf;
318 StringRef Name = sanitizeFilenameAsIdentifier(
319 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
320 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000321 Found = lookupModuleQualified(Name, Found);
322 if (!Found)
323 return false;
324 if (!Found->isAvailable())
325 return true;
326 }
327
328 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000329 SmallString<32> NameBuf;
330 StringRef Name = sanitizeFilenameAsIdentifier(
331 llvm::sys::path::stem(Header->getName()),
332 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000333 Found = lookupModuleQualified(Name, Found);
334 if (!Found)
335 return false;
336 }
337
338 return !Found->isAvailable();
339 }
340
341 SkippedDirs.push_back(Dir);
342
343 // Retrieve our parent path.
344 DirName = llvm::sys::path::parent_path(DirName);
345 if (DirName.empty())
346 break;
347
348 // Resolve the parent path to a directory entry.
349 Dir = SourceMgr->getFileManager().getDirectory(DirName);
350 } while (Dir);
351
352 return false;
353}
354
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000355Module *ModuleMap::findModule(StringRef Name) const {
356 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor484535e2011-11-11 23:20:24 +0000357 if (Known != Modules.end())
358 return Known->getValue();
359
360 return 0;
361}
362
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000363Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
364 Module *Context) const {
Douglas Gregor90db2602011-12-02 01:47:07 +0000365 for(; Context; Context = Context->Parent) {
366 if (Module *Sub = lookupModuleQualified(Name, Context))
367 return Sub;
368 }
369
370 return findModule(Name);
371}
372
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000373Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor90db2602011-12-02 01:47:07 +0000374 if (!Context)
375 return findModule(Name);
376
Douglas Gregorb7a78192012-01-04 23:32:19 +0000377 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000378}
379
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000380std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000381ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
382 bool IsExplicit) {
383 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000384 if (Module *Sub = lookupModuleQualified(Name, Parent))
385 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000386
387 // Create a new module with this name.
388 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
389 IsExplicit);
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000390 if (!Parent) {
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000391 Modules[Name] = Result;
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000392 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
393 Name == LangOpts.CurrentModule) {
394 CompilingModule = Result;
395 }
396 }
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000397 return std::make_pair(Result, true);
398}
399
Douglas Gregor82e52372012-11-06 19:39:40 +0000400bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000401 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000402 // Check whether we have already looked into the parent directory
403 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000404 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000405 inferred = InferredDirectories.find(ParentDir);
406 if (inferred == InferredDirectories.end())
407 return false;
408
409 if (!inferred->second.InferModules)
410 return false;
411
412 // We're allowed to infer for this directory, but make sure it's okay
413 // to infer this particular module.
414 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
415 inferred->second.ExcludedModules.end(),
416 Name) == inferred->second.ExcludedModules.end();
417
418 if (canInfer && inferred->second.InferSystemModules)
419 IsSystem = true;
420
421 return canInfer;
422}
423
Douglas Gregor8767dc22013-01-14 17:57:51 +0000424/// \brief For a framework module, infer the framework against which we
425/// should link.
426static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
427 FileManager &FileMgr) {
428 assert(Mod->IsFramework && "Can only infer linking for framework modules");
429 assert(!Mod->isSubFramework() &&
430 "Can only infer linking for top-level frameworks");
431
432 SmallString<128> LibName;
433 LibName += FrameworkDir->getName();
434 llvm::sys::path::append(LibName, Mod->Name);
435 if (FileMgr.getFile(LibName)) {
436 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
437 /*IsFramework=*/true));
438 }
439}
440
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000441Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000442ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000443 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000444 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000445 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000446 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000447 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
448 return Mod;
449
450 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000451
452 // If the framework has a parent path from which we're allowed to infer
453 // a framework module, do so.
454 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000455 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000456
Douglas Gregor7005b902013-01-10 01:43:00 +0000457 // Note: as an egregious but useful hack we use the real path here, because
458 // we might be looking at an embedded framework that symlinks out to a
459 // top-level framework, and we need to infer as if we were naming the
460 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000461 StringRef FrameworkDirName
462 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000463
Douglas Gregor82e52372012-11-06 19:39:40 +0000464 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000465 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000466 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000467 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000468 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
469 // Check whether we have already looked into the parent directory
470 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000471 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000472 inferred = InferredDirectories.find(ParentDir);
473 if (inferred == InferredDirectories.end()) {
474 // We haven't looked here before. Load a module map, if there is
475 // one.
476 SmallString<128> ModMapPath = Parent;
477 llvm::sys::path::append(ModMapPath, "module.map");
478 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000479 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor82e52372012-11-06 19:39:40 +0000480 inferred = InferredDirectories.find(ParentDir);
481 }
482
483 if (inferred == InferredDirectories.end())
484 inferred = InferredDirectories.insert(
485 std::make_pair(ParentDir, InferredDirectory())).first;
486 }
487
488 if (inferred->second.InferModules) {
489 // We're allowed to infer for this directory, but make sure it's okay
490 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000491 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000492 canInfer = std::find(inferred->second.ExcludedModules.begin(),
493 inferred->second.ExcludedModules.end(),
494 Name) == inferred->second.ExcludedModules.end();
495
496 if (inferred->second.InferSystemModules)
497 IsSystem = true;
498 }
499 }
500 }
501
502 // If we're not allowed to infer a framework module, don't.
503 if (!canInfer)
504 return 0;
505 }
506
507
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000508 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000509 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramerceb6dc82013-06-28 16:25:46 +0000510 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000511 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000512
513 // FIXME: If there's no umbrella header, we could probably scan the
514 // framework to load *everything*. But, it's not clear that this is a good
515 // idea.
516 if (!UmbrellaHeader)
517 return 0;
518
Douglas Gregorac252a32011-12-06 19:39:29 +0000519 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
520 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000521 if (IsSystem)
522 Result->IsSystem = IsSystem;
523
Douglas Gregorb7a78192012-01-04 23:32:19 +0000524 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000525 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000526
Douglas Gregor489ad432011-12-08 18:00:48 +0000527 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000528 Result->Umbrella = UmbrellaHeader;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000529 Headers[UmbrellaHeader] = KnownHeader(Result, NormalHeader);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000530 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000531
532 // export *
533 Result->Exports.push_back(Module::ExportDecl(0, true));
534
Douglas Gregore209e502011-12-06 01:10:29 +0000535 // module * { export * }
536 Result->InferSubmodules = true;
537 Result->InferExportWildcard = true;
538
Douglas Gregorac252a32011-12-06 19:39:29 +0000539 // Look for subframeworks.
540 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000541 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000542 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000543 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000544 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000545 llvm::sys::path::native(SubframeworksDirName.str(),
546 SubframeworksDirNameNative);
547 for (llvm::sys::fs::directory_iterator
548 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000549 Dir != DirEnd && !EC; Dir.increment(EC)) {
550 if (!StringRef(Dir->path()).endswith(".framework"))
551 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000552
Douglas Gregorac252a32011-12-06 19:39:29 +0000553 if (const DirectoryEntry *SubframeworkDir
554 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000555 // Note: as an egregious but useful hack, we use the real path here and
556 // check whether it is actually a subdirectory of the parent directory.
557 // This will not be the case if the 'subframework' is actually a symlink
558 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000559 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
560 bool FoundParent = false;
561 do {
562 // Get the parent directory name.
563 SubframeworkDirName
564 = llvm::sys::path::parent_path(SubframeworkDirName);
565 if (SubframeworkDirName.empty())
566 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000567
Douglas Gregor713b7c02013-01-26 00:55:12 +0000568 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
569 FoundParent = true;
570 break;
571 }
572 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000573
Douglas Gregor713b7c02013-01-26 00:55:12 +0000574 if (!FoundParent)
575 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000576
Douglas Gregorac252a32011-12-06 19:39:29 +0000577 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000578 SmallString<32> NameBuf;
579 inferFrameworkModule(sanitizeFilenameAsIdentifier(
580 llvm::sys::path::stem(Dir->path()), NameBuf),
581 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000582 }
583 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000584
Douglas Gregor8767dc22013-01-14 17:57:51 +0000585 // If the module is a top-level framework, automatically link against the
586 // framework.
587 if (!Result->isSubFramework()) {
588 inferFrameworkLink(Result, FrameworkDir, FileMgr);
589 }
590
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000591 return Result;
592}
593
Douglas Gregore209e502011-12-06 01:10:29 +0000594void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000595 Headers[UmbrellaHeader] = KnownHeader(Mod, NormalHeader);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000596 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000597 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000598}
599
Douglas Gregor77d029f2011-12-08 19:11:24 +0000600void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
601 Mod->Umbrella = UmbrellaDir;
602 UmbrellaDirs[UmbrellaDir] = Mod;
603}
604
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000605void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000606 ModuleHeaderRole Role) {
607 if (Role == ExcludedHeader) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000608 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000609 } else {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000610 if (Role == PrivateHeader)
611 Mod->PrivateHeaders.push_back(Header);
612 else
613 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000614 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000615 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000616 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000617 Headers[Header] = KnownHeader(Mod, Role);
Douglas Gregore209e502011-12-06 01:10:29 +0000618}
619
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000620const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000621ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000622 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
623 return 0;
624
625 return SourceMgr->getFileEntryForID(
626 SourceMgr->getFileID(Module->DefinitionLoc));
627}
628
Douglas Gregora30cfe52011-11-11 19:10:28 +0000629void ModuleMap::dump() {
630 llvm::errs() << "Modules:";
631 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
632 MEnd = Modules.end();
633 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000634 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000635
636 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000637 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000638 H != HEnd; ++H) {
639 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000640 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000641 }
642}
643
Douglas Gregor90db2602011-12-02 01:47:07 +0000644bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
645 bool HadError = false;
646 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
647 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
648 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000649 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000650 Mod->Exports.push_back(Export);
651 else
652 HadError = true;
653 }
654 Mod->UnresolvedExports.clear();
655 return HadError;
656}
657
Douglas Gregor906d66a2013-03-20 21:10:35 +0000658bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
659 bool HadError = false;
660 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
661 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
662 Mod, Complain);
663 if (!OtherMod) {
664 HadError = true;
665 continue;
666 }
667
668 Module::Conflict Conflict;
669 Conflict.Other = OtherMod;
670 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
671 Mod->Conflicts.push_back(Conflict);
672 }
673 Mod->UnresolvedConflicts.clear();
674 return HadError;
675}
676
Douglas Gregor55988682011-12-05 16:33:54 +0000677Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
678 if (Loc.isInvalid())
679 return 0;
680
681 // Use the expansion location to determine which module we're in.
682 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
683 if (!ExpansionLoc.isFileID())
684 return 0;
685
686
687 const SourceManager &SrcMgr = Loc.getManager();
688 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000689
Douglas Gregor303aae92012-01-06 17:19:32 +0000690 while (const FileEntry *ExpansionFile
691 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
692 // Find the module that owns this header (if any).
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000693 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor303aae92012-01-06 17:19:32 +0000694 return Mod;
695
696 // No module owns this header, so look up the inclusion chain to see if
697 // any included header has an associated module.
698 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
699 if (IncludeLoc.isInvalid())
700 return 0;
701
702 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
703 }
704
705 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000706}
707
Douglas Gregora30cfe52011-11-11 19:10:28 +0000708//----------------------------------------------------------------------------//
709// Module map file parser
710//----------------------------------------------------------------------------//
711
712namespace clang {
713 /// \brief A token in a module map file.
714 struct MMToken {
715 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000716 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000717 ConfigMacros,
Douglas Gregor906d66a2013-03-20 21:10:35 +0000718 Conflict,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000719 EndOfFile,
720 HeaderKeyword,
721 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000722 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000723 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000724 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000725 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000726 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000727 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000728 Period,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000729 PrivateKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000730 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000731 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000732 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000733 StringLiteral,
734 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000735 RBrace,
736 LSquare,
737 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000738 } Kind;
739
740 unsigned Location;
741 unsigned StringLength;
742 const char *StringData;
743
744 void clear() {
745 Kind = EndOfFile;
746 Location = 0;
747 StringLength = 0;
748 StringData = 0;
749 }
750
751 bool is(TokenKind K) const { return Kind == K; }
752
753 SourceLocation getLocation() const {
754 return SourceLocation::getFromRawEncoding(Location);
755 }
756
757 StringRef getString() const {
758 return StringRef(StringData, StringLength);
759 }
760 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000761
762 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000763 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000764 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000765
766 /// \brief Whether this is a system module.
767 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000768
769 /// \brief Whether this is an exhaustive set of configuration macros.
770 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000771 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000772
Douglas Gregor82e52372012-11-06 19:39:40 +0000773
Douglas Gregora30cfe52011-11-11 19:10:28 +0000774 class ModuleMapParser {
775 Lexer &L;
776 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000777
778 /// \brief Default target information, used only for string literal
779 /// parsing.
780 const TargetInfo *Target;
781
Douglas Gregora30cfe52011-11-11 19:10:28 +0000782 DiagnosticsEngine &Diags;
783 ModuleMap &Map;
784
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000785 /// \brief The directory that this module map resides in.
786 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000787
788 /// \brief The directory containing Clang-supplied headers.
789 const DirectoryEntry *BuiltinIncludeDir;
790
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000791 /// \brief Whether this module map is in a system header directory.
792 bool IsSystem;
793
Douglas Gregora30cfe52011-11-11 19:10:28 +0000794 /// \brief Whether an error occurred.
795 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000796
Douglas Gregora30cfe52011-11-11 19:10:28 +0000797 /// \brief Stores string data for the various string literals referenced
798 /// during parsing.
799 llvm::BumpPtrAllocator StringData;
800
801 /// \brief The current token.
802 MMToken Tok;
803
804 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000805 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000806
807 /// \brief Consume the current token and return its location.
808 SourceLocation consumeToken();
809
810 /// \brief Skip tokens until we reach the a token with the given kind
811 /// (or the end of the file).
812 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000813
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000814 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000815 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000816 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000817 void parseRequiresDecl();
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000818 void parseHeaderDecl(clang::MMToken::TokenKind,
819 SourceLocation LeadingLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000820 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000821 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000822 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000823 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000824 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000825 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000826 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000827
Douglas Gregor6a1db482011-12-09 02:04:43 +0000828 const DirectoryEntry *getOverriddenHeaderSearchDir();
829
Douglas Gregora30cfe52011-11-11 19:10:28 +0000830 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000831 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000832 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000833 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000834 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000835 const DirectoryEntry *Directory,
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000836 const DirectoryEntry *BuiltinIncludeDir,
837 bool IsSystem)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000838 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000839 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
840 IsSystem(IsSystem), HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000841 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000842 Tok.clear();
843 consumeToken();
844 }
845
846 bool parseModuleMapFile();
847 };
848}
849
850SourceLocation ModuleMapParser::consumeToken() {
851retry:
852 SourceLocation Result = Tok.getLocation();
853 Tok.clear();
854
855 Token LToken;
856 L.LexFromRawLexer(LToken);
857 Tok.Location = LToken.getLocation().getRawEncoding();
858 switch (LToken.getKind()) {
859 case tok::raw_identifier:
860 Tok.StringData = LToken.getRawIdentifierData();
861 Tok.StringLength = LToken.getLength();
862 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000863 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000864 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000865 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000866 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000867 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000868 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000869 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000870 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000871 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000872 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000873 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000874 .Case("umbrella", MMToken::UmbrellaKeyword)
875 .Default(MMToken::Identifier);
876 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000877
878 case tok::comma:
879 Tok.Kind = MMToken::Comma;
880 break;
881
Douglas Gregora30cfe52011-11-11 19:10:28 +0000882 case tok::eof:
883 Tok.Kind = MMToken::EndOfFile;
884 break;
885
886 case tok::l_brace:
887 Tok.Kind = MMToken::LBrace;
888 break;
889
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000890 case tok::l_square:
891 Tok.Kind = MMToken::LSquare;
892 break;
893
Douglas Gregor90db2602011-12-02 01:47:07 +0000894 case tok::period:
895 Tok.Kind = MMToken::Period;
896 break;
897
Douglas Gregora30cfe52011-11-11 19:10:28 +0000898 case tok::r_brace:
899 Tok.Kind = MMToken::RBrace;
900 break;
901
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000902 case tok::r_square:
903 Tok.Kind = MMToken::RSquare;
904 break;
905
Douglas Gregor90db2602011-12-02 01:47:07 +0000906 case tok::star:
907 Tok.Kind = MMToken::Star;
908 break;
909
Douglas Gregora30cfe52011-11-11 19:10:28 +0000910 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000911 if (LToken.hasUDSuffix()) {
912 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
913 HadError = true;
914 goto retry;
915 }
916
Douglas Gregora30cfe52011-11-11 19:10:28 +0000917 // Parse the string literal.
918 LangOptions LangOpts;
919 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
920 if (StringLiteral.hadError)
921 goto retry;
922
923 // Copy the string literal into our string data allocator.
924 unsigned Length = StringLiteral.GetStringLength();
925 char *Saved = StringData.Allocate<char>(Length + 1);
926 memcpy(Saved, StringLiteral.GetString().data(), Length);
927 Saved[Length] = 0;
928
929 // Form the token.
930 Tok.Kind = MMToken::StringLiteral;
931 Tok.StringData = Saved;
932 Tok.StringLength = Length;
933 break;
934 }
935
936 case tok::comment:
937 goto retry;
938
939 default:
940 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
941 HadError = true;
942 goto retry;
943 }
944
945 return Result;
946}
947
948void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
949 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000950 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000951 do {
952 switch (Tok.Kind) {
953 case MMToken::EndOfFile:
954 return;
955
956 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000957 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000958 return;
959
960 ++braceDepth;
961 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000962
963 case MMToken::LSquare:
964 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
965 return;
966
967 ++squareDepth;
968 break;
969
Douglas Gregora30cfe52011-11-11 19:10:28 +0000970 case MMToken::RBrace:
971 if (braceDepth > 0)
972 --braceDepth;
973 else if (Tok.is(K))
974 return;
975 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000976
977 case MMToken::RSquare:
978 if (squareDepth > 0)
979 --squareDepth;
980 else if (Tok.is(K))
981 return;
982 break;
983
Douglas Gregora30cfe52011-11-11 19:10:28 +0000984 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000985 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000986 return;
987 break;
988 }
989
990 consumeToken();
991 } while (true);
992}
993
Douglas Gregor587986e2011-12-07 02:23:45 +0000994/// \brief Parse a module-id.
995///
996/// module-id:
997/// identifier
998/// identifier '.' module-id
999///
1000/// \returns true if an error occurred, false otherwise.
1001bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1002 Id.clear();
1003 do {
1004 if (Tok.is(MMToken::Identifier)) {
1005 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1006 consumeToken();
1007 } else {
1008 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1009 return true;
1010 }
1011
1012 if (!Tok.is(MMToken::Period))
1013 break;
1014
1015 consumeToken();
1016 } while (true);
1017
1018 return false;
1019}
1020
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001021namespace {
1022 /// \brief Enumerates the known attributes.
1023 enum AttributeKind {
1024 /// \brief An unknown attribute.
1025 AT_unknown,
1026 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001027 AT_system,
1028 /// \brief The 'exhaustive' attribute.
1029 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001030 };
1031}
1032
Douglas Gregora30cfe52011-11-11 19:10:28 +00001033/// \brief Parse a module declaration.
1034///
1035/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001036/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1037/// { module-member* }
1038///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001039/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001040/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001041/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001042/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001043/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001044/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001045///
1046/// submodule-declaration:
1047/// module-declaration
1048/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001049void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001050 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1051 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +00001052 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001053 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001054 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001055 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001056
Douglas Gregord620a842011-12-06 17:16:41 +00001057 // Parse 'explicit' keyword, if present.
1058 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001059 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001060 Explicit = true;
1061 }
1062
1063 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001064 if (Tok.is(MMToken::FrameworkKeyword)) {
1065 consumeToken();
1066 Framework = true;
1067 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001068
1069 // Parse 'module' keyword.
1070 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001071 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001072 consumeToken();
1073 HadError = true;
1074 return;
1075 }
1076 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001077
1078 // If we have a wildcard for the module name, this is an inferred submodule.
1079 // Parse it.
1080 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001081 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001082
1083 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001084 ModuleId Id;
1085 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001086 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001087 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001088 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001089
Douglas Gregor587986e2011-12-07 02:23:45 +00001090 if (ActiveModule) {
1091 if (Id.size() > 1) {
1092 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1093 << SourceRange(Id.front().second, Id.back().second);
1094
1095 HadError = true;
1096 return;
1097 }
1098 } else if (Id.size() == 1 && Explicit) {
1099 // Top-level modules can't be explicit.
1100 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1101 Explicit = false;
1102 ExplicitLoc = SourceLocation();
1103 HadError = true;
1104 }
1105
1106 Module *PreviousActiveModule = ActiveModule;
1107 if (Id.size() > 1) {
1108 // This module map defines a submodule. Go find the module of which it
1109 // is a submodule.
1110 ActiveModule = 0;
1111 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1112 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1113 ActiveModule = Next;
1114 continue;
1115 }
1116
1117 if (ActiveModule) {
1118 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1119 << Id[I].first << ActiveModule->getTopLevelModule();
1120 } else {
1121 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1122 }
1123 HadError = true;
1124 return;
1125 }
1126 }
1127
1128 StringRef ModuleName = Id.back().first;
1129 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001130
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001131 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001132 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001133 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001134
Douglas Gregora30cfe52011-11-11 19:10:28 +00001135 // Parse the opening brace.
1136 if (!Tok.is(MMToken::LBrace)) {
1137 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1138 << ModuleName;
1139 HadError = true;
1140 return;
1141 }
1142 SourceLocation LBraceLoc = consumeToken();
1143
1144 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001145 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001146 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1147 // Skip the module definition.
1148 skipUntil(MMToken::RBrace);
1149 if (Tok.is(MMToken::RBrace))
1150 consumeToken();
1151 else {
1152 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1153 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1154 HadError = true;
1155 }
1156 return;
1157 }
1158
Douglas Gregora30cfe52011-11-11 19:10:28 +00001159 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1160 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001161 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001162
1163 // Skip the module definition.
1164 skipUntil(MMToken::RBrace);
1165 if (Tok.is(MMToken::RBrace))
1166 consumeToken();
1167
1168 HadError = true;
1169 return;
1170 }
1171
1172 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001173 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1174 Explicit).first;
1175 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001176 if (Attrs.IsSystem || IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001177 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001178
1179 bool Done = false;
1180 do {
1181 switch (Tok.Kind) {
1182 case MMToken::EndOfFile:
1183 case MMToken::RBrace:
1184 Done = true;
1185 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001186
1187 case MMToken::ConfigMacros:
1188 parseConfigMacros();
1189 break;
1190
Douglas Gregor906d66a2013-03-20 21:10:35 +00001191 case MMToken::Conflict:
1192 parseConflict();
1193 break;
1194
Douglas Gregora30cfe52011-11-11 19:10:28 +00001195 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001196 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001197 case MMToken::ModuleKeyword:
1198 parseModuleDecl();
1199 break;
1200
Douglas Gregor90db2602011-12-02 01:47:07 +00001201 case MMToken::ExportKeyword:
1202 parseExportDecl();
1203 break;
1204
Douglas Gregor51f564f2011-12-31 04:05:44 +00001205 case MMToken::RequiresKeyword:
1206 parseRequiresDecl();
1207 break;
1208
Douglas Gregor77d029f2011-12-08 19:11:24 +00001209 case MMToken::UmbrellaKeyword: {
1210 SourceLocation UmbrellaLoc = consumeToken();
1211 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001212 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +00001213 else
1214 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001215 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001216 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001217
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001218 case MMToken::ExcludeKeyword: {
1219 SourceLocation ExcludeLoc = consumeToken();
1220 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001221 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001222 } else {
1223 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1224 << "exclude";
1225 }
1226 break;
1227 }
1228
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001229 case MMToken::PrivateKeyword: {
1230 SourceLocation PrivateLoc = consumeToken();
1231 if (Tok.is(MMToken::HeaderKeyword)) {
1232 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1233 } else {
1234 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1235 << "private";
1236 }
1237 break;
1238 }
1239
Douglas Gregor489ad432011-12-08 18:00:48 +00001240 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001241 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001242 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001243
1244 case MMToken::LinkKeyword:
1245 parseLinkDecl();
1246 break;
1247
Douglas Gregora30cfe52011-11-11 19:10:28 +00001248 default:
1249 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1250 consumeToken();
1251 break;
1252 }
1253 } while (!Done);
1254
1255 if (Tok.is(MMToken::RBrace))
1256 consumeToken();
1257 else {
1258 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1259 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1260 HadError = true;
1261 }
1262
Douglas Gregor8767dc22013-01-14 17:57:51 +00001263 // If the active module is a top-level framework, and there are no link
1264 // libraries, automatically link against the framework.
1265 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1266 ActiveModule->LinkLibraries.empty()) {
1267 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1268 }
1269
Douglas Gregor587986e2011-12-07 02:23:45 +00001270 // We're done parsing this module. Pop back to the previous module.
1271 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001272}
Douglas Gregord620a842011-12-06 17:16:41 +00001273
Douglas Gregor51f564f2011-12-31 04:05:44 +00001274/// \brief Parse a requires declaration.
1275///
1276/// requires-declaration:
1277/// 'requires' feature-list
1278///
1279/// feature-list:
1280/// identifier ',' feature-list
1281/// identifier
1282void ModuleMapParser::parseRequiresDecl() {
1283 assert(Tok.is(MMToken::RequiresKeyword));
1284
1285 // Parse 'requires' keyword.
1286 consumeToken();
1287
1288 // Parse the feature-list.
1289 do {
1290 if (!Tok.is(MMToken::Identifier)) {
1291 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1292 HadError = true;
1293 return;
1294 }
1295
1296 // Consume the feature name.
1297 std::string Feature = Tok.getString();
1298 consumeToken();
1299
1300 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001301 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001302
1303 if (!Tok.is(MMToken::Comma))
1304 break;
1305
1306 // Consume the comma.
1307 consumeToken();
1308 } while (true);
1309}
1310
Douglas Gregord620a842011-12-06 17:16:41 +00001311/// \brief Append to \p Paths the set of paths needed to get to the
1312/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001313static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001314 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001315 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001316 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001317 for (; Mod; Mod = Mod->Parent) {
1318 if (Mod->IsFramework)
1319 Paths.push_back(Mod->Name);
1320 }
1321
1322 if (Paths.empty())
1323 return;
1324
1325 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001326 for (unsigned I = Paths.size() - 1; I != 0; --I)
1327 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregord620a842011-12-06 17:16:41 +00001328}
1329
Douglas Gregora30cfe52011-11-11 19:10:28 +00001330/// \brief Parse a header declaration.
1331///
1332/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001333/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001334/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001335void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1336 SourceLocation LeadingLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001337 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001338 consumeToken();
1339
Douglas Gregora30cfe52011-11-11 19:10:28 +00001340 // Parse the header name.
1341 if (!Tok.is(MMToken::StringLiteral)) {
1342 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1343 << "header";
1344 HadError = true;
1345 return;
1346 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001347 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001348 SourceLocation FileNameLoc = consumeToken();
1349
Douglas Gregor77d029f2011-12-08 19:11:24 +00001350 // Check whether we already have an umbrella.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001351 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Douglas Gregor77d029f2011-12-08 19:11:24 +00001352 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1353 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001354 HadError = true;
1355 return;
1356 }
1357
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001358 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001359 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001360 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001361 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001362 if (llvm::sys::path::is_absolute(FileName)) {
1363 PathName = FileName;
1364 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001365 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1366 PathName = Dir->getName();
1367 llvm::sys::path::append(PathName, FileName);
1368 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001369 } else {
1370 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001371 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001372 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001373
Douglas Gregord620a842011-12-06 17:16:41 +00001374 if (ActiveModule->isPartOfFramework()) {
1375 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001376
1377 // Check whether this file is in the public headers.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001378 llvm::sys::path::append(PathName, "Headers", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001379 File = SourceMgr.getFileManager().getFile(PathName);
1380
1381 if (!File) {
1382 // Check whether this file is in the private headers.
1383 PathName.resize(PathLength);
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001384 llvm::sys::path::append(PathName, "PrivateHeaders", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001385 File = SourceMgr.getFileManager().getFile(PathName);
1386 }
1387 } else {
1388 // Lookup for normal headers.
1389 llvm::sys::path::append(PathName, FileName);
1390 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001391
1392 // If this is a system module with a top-level header, this header
1393 // may have a counterpart (or replacement) in the set of headers
1394 // supplied by Clang. Find that builtin header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001395 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1396 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1397 isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001398 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001399 llvm::sys::path::append(BuiltinPathName, FileName);
1400 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1401
1402 // If Clang supplies this header but the underlying system does not,
1403 // just silently swap in our builtin version. Otherwise, we'll end
1404 // up adding both (later).
1405 if (!File && BuiltinFile) {
1406 File = BuiltinFile;
1407 BuiltinFile = 0;
1408 }
1409 }
Douglas Gregord620a842011-12-06 17:16:41 +00001410 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001411 }
Douglas Gregora8654052011-11-17 22:09:43 +00001412
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001413 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1414 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001415 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001416 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001417 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001418 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001419 HadError = true;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001420 } else if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001421 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001422 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001423 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001424 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001425 HadError = true;
1426 } else {
1427 // Record this umbrella header.
1428 Map.setUmbrellaHeader(ActiveModule, File);
1429 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001430 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001431 // Record this header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001432 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1433 if (LeadingToken == MMToken::ExcludeKeyword)
1434 Role = ModuleMap::ExcludedHeader;
1435 else if (LeadingToken == MMToken::PrivateKeyword)
1436 Role = ModuleMap::PrivateHeader;
1437 else
1438 assert(LeadingToken == MMToken::HeaderKeyword);
1439
1440 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001441
1442 // If there is a builtin counterpart to this file, add it now.
1443 if (BuiltinFile)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001444 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001445 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001446 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor71f49f52012-11-15 19:47:16 +00001447 // Ignore excluded header files. They're optional anyway.
1448
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001449 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001450 << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001451 HadError = true;
1452 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001453}
1454
Douglas Gregor77d029f2011-12-08 19:11:24 +00001455/// \brief Parse an umbrella directory declaration.
1456///
1457/// umbrella-dir-declaration:
1458/// umbrella string-literal
1459void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1460 // Parse the directory name.
1461 if (!Tok.is(MMToken::StringLiteral)) {
1462 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1463 << "umbrella";
1464 HadError = true;
1465 return;
1466 }
1467
1468 std::string DirName = Tok.getString();
1469 SourceLocation DirNameLoc = consumeToken();
1470
1471 // Check whether we already have an umbrella.
1472 if (ActiveModule->Umbrella) {
1473 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1474 << ActiveModule->getFullModuleName();
1475 HadError = true;
1476 return;
1477 }
1478
1479 // Look for this file.
1480 const DirectoryEntry *Dir = 0;
1481 if (llvm::sys::path::is_absolute(DirName))
1482 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1483 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001484 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001485 PathName = Directory->getName();
1486 llvm::sys::path::append(PathName, DirName);
1487 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1488 }
1489
1490 if (!Dir) {
1491 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1492 << DirName;
1493 HadError = true;
1494 return;
1495 }
1496
1497 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1498 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1499 << OwningModule->getFullModuleName();
1500 HadError = true;
1501 return;
1502 }
1503
1504 // Record this umbrella directory.
1505 Map.setUmbrellaDir(ActiveModule, Dir);
1506}
1507
Douglas Gregor90db2602011-12-02 01:47:07 +00001508/// \brief Parse a module export declaration.
1509///
1510/// export-declaration:
1511/// 'export' wildcard-module-id
1512///
1513/// wildcard-module-id:
1514/// identifier
1515/// '*'
1516/// identifier '.' wildcard-module-id
1517void ModuleMapParser::parseExportDecl() {
1518 assert(Tok.is(MMToken::ExportKeyword));
1519 SourceLocation ExportLoc = consumeToken();
1520
1521 // Parse the module-id with an optional wildcard at the end.
1522 ModuleId ParsedModuleId;
1523 bool Wildcard = false;
1524 do {
1525 if (Tok.is(MMToken::Identifier)) {
1526 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1527 Tok.getLocation()));
1528 consumeToken();
1529
1530 if (Tok.is(MMToken::Period)) {
1531 consumeToken();
1532 continue;
1533 }
1534
1535 break;
1536 }
1537
1538 if(Tok.is(MMToken::Star)) {
1539 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001540 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001541 break;
1542 }
1543
1544 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1545 HadError = true;
1546 return;
1547 } while (true);
1548
1549 Module::UnresolvedExportDecl Unresolved = {
1550 ExportLoc, ParsedModuleId, Wildcard
1551 };
1552 ActiveModule->UnresolvedExports.push_back(Unresolved);
1553}
1554
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001555/// \brief Parse a link declaration.
1556///
1557/// module-declaration:
1558/// 'link' 'framework'[opt] string-literal
1559void ModuleMapParser::parseLinkDecl() {
1560 assert(Tok.is(MMToken::LinkKeyword));
1561 SourceLocation LinkLoc = consumeToken();
1562
1563 // Parse the optional 'framework' keyword.
1564 bool IsFramework = false;
1565 if (Tok.is(MMToken::FrameworkKeyword)) {
1566 consumeToken();
1567 IsFramework = true;
1568 }
1569
1570 // Parse the library name
1571 if (!Tok.is(MMToken::StringLiteral)) {
1572 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1573 << IsFramework << SourceRange(LinkLoc);
1574 HadError = true;
1575 return;
1576 }
1577
1578 std::string LibraryName = Tok.getString();
1579 consumeToken();
1580 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1581 IsFramework));
1582}
1583
Douglas Gregor63a72682013-03-20 00:22:05 +00001584/// \brief Parse a configuration macro declaration.
1585///
1586/// module-declaration:
1587/// 'config_macros' attributes[opt] config-macro-list?
1588///
1589/// config-macro-list:
1590/// identifier (',' identifier)?
1591void ModuleMapParser::parseConfigMacros() {
1592 assert(Tok.is(MMToken::ConfigMacros));
1593 SourceLocation ConfigMacrosLoc = consumeToken();
1594
1595 // Only top-level modules can have configuration macros.
1596 if (ActiveModule->Parent) {
1597 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1598 }
1599
1600 // Parse the optional attributes.
1601 Attributes Attrs;
1602 parseOptionalAttributes(Attrs);
1603 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1604 ActiveModule->ConfigMacrosExhaustive = true;
1605 }
1606
1607 // If we don't have an identifier, we're done.
1608 if (!Tok.is(MMToken::Identifier))
1609 return;
1610
1611 // Consume the first identifier.
1612 if (!ActiveModule->Parent) {
1613 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1614 }
1615 consumeToken();
1616
1617 do {
1618 // If there's a comma, consume it.
1619 if (!Tok.is(MMToken::Comma))
1620 break;
1621 consumeToken();
1622
1623 // We expect to see a macro name here.
1624 if (!Tok.is(MMToken::Identifier)) {
1625 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1626 break;
1627 }
1628
1629 // Consume the macro name.
1630 if (!ActiveModule->Parent) {
1631 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1632 }
1633 consumeToken();
1634 } while (true);
1635}
1636
Douglas Gregor906d66a2013-03-20 21:10:35 +00001637/// \brief Format a module-id into a string.
1638static std::string formatModuleId(const ModuleId &Id) {
1639 std::string result;
1640 {
1641 llvm::raw_string_ostream OS(result);
1642
1643 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1644 if (I)
1645 OS << ".";
1646 OS << Id[I].first;
1647 }
1648 }
1649
1650 return result;
1651}
1652
1653/// \brief Parse a conflict declaration.
1654///
1655/// module-declaration:
1656/// 'conflict' module-id ',' string-literal
1657void ModuleMapParser::parseConflict() {
1658 assert(Tok.is(MMToken::Conflict));
1659 SourceLocation ConflictLoc = consumeToken();
1660 Module::UnresolvedConflict Conflict;
1661
1662 // Parse the module-id.
1663 if (parseModuleId(Conflict.Id))
1664 return;
1665
1666 // Parse the ','.
1667 if (!Tok.is(MMToken::Comma)) {
1668 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1669 << SourceRange(ConflictLoc);
1670 return;
1671 }
1672 consumeToken();
1673
1674 // Parse the message.
1675 if (!Tok.is(MMToken::StringLiteral)) {
1676 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1677 << formatModuleId(Conflict.Id);
1678 return;
1679 }
1680 Conflict.Message = Tok.getString().str();
1681 consumeToken();
1682
1683 // Add this unresolved conflict.
1684 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1685}
1686
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001687/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001688///
1689/// module-declaration:
1690/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1691/// { inferred-module-member* }
1692///
1693/// inferred-module-member:
1694/// 'export' '*'
1695/// 'exclude' identifier
1696void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001697 assert(Tok.is(MMToken::Star));
1698 SourceLocation StarLoc = consumeToken();
1699 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001700
Douglas Gregor1e123682011-12-05 22:27:44 +00001701 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001702 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001703 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1704 Failed = true;
1705 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001706
1707 if (ActiveModule) {
1708 // Inferred modules must have umbrella directories.
1709 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1710 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1711 Failed = true;
1712 }
1713
1714 // Check for redefinition of an inferred module.
1715 if (!Failed && ActiveModule->InferSubmodules) {
1716 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1717 if (ActiveModule->InferredSubmoduleLoc.isValid())
1718 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1719 diag::note_mmap_prev_definition);
1720 Failed = true;
1721 }
1722
1723 // Check for the 'framework' keyword, which is not permitted here.
1724 if (Framework) {
1725 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1726 Framework = false;
1727 }
1728 } else if (Explicit) {
1729 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1730 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001731 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001732
Douglas Gregor1e123682011-12-05 22:27:44 +00001733 // If there were any problems with this inferred submodule, skip its body.
1734 if (Failed) {
1735 if (Tok.is(MMToken::LBrace)) {
1736 consumeToken();
1737 skipUntil(MMToken::RBrace);
1738 if (Tok.is(MMToken::RBrace))
1739 consumeToken();
1740 }
1741 HadError = true;
1742 return;
1743 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001744
1745 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001746 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001747 parseOptionalAttributes(Attrs);
1748
1749 if (ActiveModule) {
1750 // Note that we have an inferred submodule.
1751 ActiveModule->InferSubmodules = true;
1752 ActiveModule->InferredSubmoduleLoc = StarLoc;
1753 ActiveModule->InferExplicitSubmodules = Explicit;
1754 } else {
1755 // We'll be inferring framework modules for this directory.
1756 Map.InferredDirectories[Directory].InferModules = true;
1757 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1758 }
1759
Douglas Gregor1e123682011-12-05 22:27:44 +00001760 // Parse the opening brace.
1761 if (!Tok.is(MMToken::LBrace)) {
1762 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1763 HadError = true;
1764 return;
1765 }
1766 SourceLocation LBraceLoc = consumeToken();
1767
1768 // Parse the body of the inferred submodule.
1769 bool Done = false;
1770 do {
1771 switch (Tok.Kind) {
1772 case MMToken::EndOfFile:
1773 case MMToken::RBrace:
1774 Done = true;
1775 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001776
1777 case MMToken::ExcludeKeyword: {
1778 if (ActiveModule) {
1779 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001780 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001781 consumeToken();
1782 break;
1783 }
1784
1785 consumeToken();
1786 if (!Tok.is(MMToken::Identifier)) {
1787 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1788 break;
1789 }
1790
1791 Map.InferredDirectories[Directory].ExcludedModules
1792 .push_back(Tok.getString());
1793 consumeToken();
1794 break;
1795 }
1796
1797 case MMToken::ExportKeyword:
1798 if (!ActiveModule) {
1799 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001800 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001801 consumeToken();
1802 break;
1803 }
1804
Douglas Gregor1e123682011-12-05 22:27:44 +00001805 consumeToken();
1806 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001807 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001808 else
1809 Diags.Report(Tok.getLocation(),
1810 diag::err_mmap_expected_export_wildcard);
1811 consumeToken();
1812 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001813
Douglas Gregor1e123682011-12-05 22:27:44 +00001814 case MMToken::ExplicitKeyword:
1815 case MMToken::ModuleKeyword:
1816 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001817 case MMToken::PrivateKeyword:
Douglas Gregor1e123682011-12-05 22:27:44 +00001818 case MMToken::UmbrellaKeyword:
1819 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001820 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001821 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001822 consumeToken();
1823 break;
1824 }
1825 } while (!Done);
1826
1827 if (Tok.is(MMToken::RBrace))
1828 consumeToken();
1829 else {
1830 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1831 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1832 HadError = true;
1833 }
1834}
1835
Douglas Gregor82e52372012-11-06 19:39:40 +00001836/// \brief Parse optional attributes.
1837///
1838/// attributes:
1839/// attribute attributes
1840/// attribute
1841///
1842/// attribute:
1843/// [ identifier ]
1844///
1845/// \param Attrs Will be filled in with the parsed attributes.
1846///
1847/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001848bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001849 bool HadError = false;
1850
1851 while (Tok.is(MMToken::LSquare)) {
1852 // Consume the '['.
1853 SourceLocation LSquareLoc = consumeToken();
1854
1855 // Check whether we have an attribute name here.
1856 if (!Tok.is(MMToken::Identifier)) {
1857 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1858 skipUntil(MMToken::RSquare);
1859 if (Tok.is(MMToken::RSquare))
1860 consumeToken();
1861 HadError = true;
1862 }
1863
1864 // Decode the attribute name.
1865 AttributeKind Attribute
1866 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001867 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00001868 .Case("system", AT_system)
1869 .Default(AT_unknown);
1870 switch (Attribute) {
1871 case AT_unknown:
1872 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1873 << Tok.getString();
1874 break;
1875
1876 case AT_system:
1877 Attrs.IsSystem = true;
1878 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001879
1880 case AT_exhaustive:
1881 Attrs.IsExhaustive = true;
1882 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001883 }
1884 consumeToken();
1885
1886 // Consume the ']'.
1887 if (!Tok.is(MMToken::RSquare)) {
1888 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1889 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1890 skipUntil(MMToken::RSquare);
1891 HadError = true;
1892 }
1893
1894 if (Tok.is(MMToken::RSquare))
1895 consumeToken();
1896 }
1897
1898 return HadError;
1899}
1900
Douglas Gregor6a1db482011-12-09 02:04:43 +00001901/// \brief If there is a specific header search directory due the presence
1902/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1903const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1904 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1905 // If we have an umbrella directory, use that.
1906 if (Mod->hasUmbrellaDir())
1907 return Mod->getUmbrellaDir();
1908
1909 // If we have a framework directory, stop looking.
1910 if (Mod->IsFramework)
1911 return 0;
1912 }
1913
1914 return 0;
1915}
1916
Douglas Gregora30cfe52011-11-11 19:10:28 +00001917/// \brief Parse a module map file.
1918///
1919/// module-map-file:
1920/// module-declaration*
1921bool ModuleMapParser::parseModuleMapFile() {
1922 do {
1923 switch (Tok.Kind) {
1924 case MMToken::EndOfFile:
1925 return HadError;
1926
Douglas Gregor587986e2011-12-07 02:23:45 +00001927 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001928 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001929 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001930 parseModuleDecl();
1931 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001932
Douglas Gregor51f564f2011-12-31 04:05:44 +00001933 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00001934 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00001935 case MMToken::Conflict:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001936 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001937 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001938 case MMToken::HeaderKeyword:
1939 case MMToken::Identifier:
1940 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001941 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001942 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001943 case MMToken::Period:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001944 case MMToken::PrivateKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001945 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001946 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001947 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001948 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001949 case MMToken::StringLiteral:
1950 case MMToken::UmbrellaKeyword:
1951 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1952 HadError = true;
1953 consumeToken();
1954 break;
1955 }
1956 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001957}
1958
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001959bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001960 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1961 = ParsedModuleMap.find(File);
1962 if (Known != ParsedModuleMap.end())
1963 return Known->second;
1964
Douglas Gregordc58aa72012-01-30 06:01:29 +00001965 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001966 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1967 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1968 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001969 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001970
1971 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001972 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1973 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001974 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001975 BuiltinIncludeDir, IsSystem);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001976 bool Result = Parser.parseModuleMapFile();
1977 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001978 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001979 return Result;
1980}