blob: 4c876f92b9928018dea6f69f0ad14f6981d6b287 [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());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000510 llvm::sys::path::append(UmbrellaName, "Headers");
511 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000512 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000513
514 // FIXME: If there's no umbrella header, we could probably scan the
515 // framework to load *everything*. But, it's not clear that this is a good
516 // idea.
517 if (!UmbrellaHeader)
518 return 0;
519
Douglas Gregorac252a32011-12-06 19:39:29 +0000520 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
521 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000522 if (IsSystem)
523 Result->IsSystem = IsSystem;
524
Douglas Gregorb7a78192012-01-04 23:32:19 +0000525 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000526 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000527
Douglas Gregor489ad432011-12-08 18:00:48 +0000528 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000529 Result->Umbrella = UmbrellaHeader;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000530 Headers[UmbrellaHeader] = KnownHeader(Result, NormalHeader);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000531 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000532
533 // export *
534 Result->Exports.push_back(Module::ExportDecl(0, true));
535
Douglas Gregore209e502011-12-06 01:10:29 +0000536 // module * { export * }
537 Result->InferSubmodules = true;
538 Result->InferExportWildcard = true;
539
Douglas Gregorac252a32011-12-06 19:39:29 +0000540 // Look for subframeworks.
541 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000542 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000543 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000544 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000545 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000546 llvm::sys::path::native(SubframeworksDirName.str(),
547 SubframeworksDirNameNative);
548 for (llvm::sys::fs::directory_iterator
549 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000550 Dir != DirEnd && !EC; Dir.increment(EC)) {
551 if (!StringRef(Dir->path()).endswith(".framework"))
552 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000553
Douglas Gregorac252a32011-12-06 19:39:29 +0000554 if (const DirectoryEntry *SubframeworkDir
555 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000556 // Note: as an egregious but useful hack, we use the real path here and
557 // check whether it is actually a subdirectory of the parent directory.
558 // This will not be the case if the 'subframework' is actually a symlink
559 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000560 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
561 bool FoundParent = false;
562 do {
563 // Get the parent directory name.
564 SubframeworkDirName
565 = llvm::sys::path::parent_path(SubframeworkDirName);
566 if (SubframeworkDirName.empty())
567 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000568
Douglas Gregor713b7c02013-01-26 00:55:12 +0000569 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
570 FoundParent = true;
571 break;
572 }
573 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000574
Douglas Gregor713b7c02013-01-26 00:55:12 +0000575 if (!FoundParent)
576 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000577
Douglas Gregorac252a32011-12-06 19:39:29 +0000578 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000579 SmallString<32> NameBuf;
580 inferFrameworkModule(sanitizeFilenameAsIdentifier(
581 llvm::sys::path::stem(Dir->path()), NameBuf),
582 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000583 }
584 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000585
Douglas Gregor8767dc22013-01-14 17:57:51 +0000586 // If the module is a top-level framework, automatically link against the
587 // framework.
588 if (!Result->isSubFramework()) {
589 inferFrameworkLink(Result, FrameworkDir, FileMgr);
590 }
591
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000592 return Result;
593}
594
Douglas Gregore209e502011-12-06 01:10:29 +0000595void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000596 Headers[UmbrellaHeader] = KnownHeader(Mod, NormalHeader);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000597 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000598 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000599}
600
Douglas Gregor77d029f2011-12-08 19:11:24 +0000601void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
602 Mod->Umbrella = UmbrellaDir;
603 UmbrellaDirs[UmbrellaDir] = Mod;
604}
605
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000606void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000607 ModuleHeaderRole Role) {
608 if (Role == ExcludedHeader) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000609 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000610 } else {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000611 if (Role == PrivateHeader)
612 Mod->PrivateHeaders.push_back(Header);
613 else
614 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000615 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000616 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000617 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000618 Headers[Header] = KnownHeader(Mod, Role);
Douglas Gregore209e502011-12-06 01:10:29 +0000619}
620
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000621const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000622ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000623 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
624 return 0;
625
626 return SourceMgr->getFileEntryForID(
627 SourceMgr->getFileID(Module->DefinitionLoc));
628}
629
Douglas Gregora30cfe52011-11-11 19:10:28 +0000630void ModuleMap::dump() {
631 llvm::errs() << "Modules:";
632 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
633 MEnd = Modules.end();
634 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000635 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000636
637 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000638 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000639 H != HEnd; ++H) {
640 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000641 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000642 }
643}
644
Douglas Gregor90db2602011-12-02 01:47:07 +0000645bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
646 bool HadError = false;
647 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
648 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
649 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000650 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000651 Mod->Exports.push_back(Export);
652 else
653 HadError = true;
654 }
655 Mod->UnresolvedExports.clear();
656 return HadError;
657}
658
Douglas Gregor906d66a2013-03-20 21:10:35 +0000659bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
660 bool HadError = false;
661 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
662 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
663 Mod, Complain);
664 if (!OtherMod) {
665 HadError = true;
666 continue;
667 }
668
669 Module::Conflict Conflict;
670 Conflict.Other = OtherMod;
671 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
672 Mod->Conflicts.push_back(Conflict);
673 }
674 Mod->UnresolvedConflicts.clear();
675 return HadError;
676}
677
Douglas Gregor55988682011-12-05 16:33:54 +0000678Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
679 if (Loc.isInvalid())
680 return 0;
681
682 // Use the expansion location to determine which module we're in.
683 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
684 if (!ExpansionLoc.isFileID())
685 return 0;
686
687
688 const SourceManager &SrcMgr = Loc.getManager();
689 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000690
Douglas Gregor303aae92012-01-06 17:19:32 +0000691 while (const FileEntry *ExpansionFile
692 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
693 // Find the module that owns this header (if any).
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000694 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor303aae92012-01-06 17:19:32 +0000695 return Mod;
696
697 // No module owns this header, so look up the inclusion chain to see if
698 // any included header has an associated module.
699 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
700 if (IncludeLoc.isInvalid())
701 return 0;
702
703 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
704 }
705
706 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000707}
708
Douglas Gregora30cfe52011-11-11 19:10:28 +0000709//----------------------------------------------------------------------------//
710// Module map file parser
711//----------------------------------------------------------------------------//
712
713namespace clang {
714 /// \brief A token in a module map file.
715 struct MMToken {
716 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000717 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000718 ConfigMacros,
Douglas Gregor906d66a2013-03-20 21:10:35 +0000719 Conflict,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000720 EndOfFile,
721 HeaderKeyword,
722 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000723 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000724 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000725 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000726 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000727 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000728 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000729 Period,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000730 PrivateKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000731 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000732 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000733 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000734 StringLiteral,
735 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000736 RBrace,
737 LSquare,
738 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000739 } Kind;
740
741 unsigned Location;
742 unsigned StringLength;
743 const char *StringData;
744
745 void clear() {
746 Kind = EndOfFile;
747 Location = 0;
748 StringLength = 0;
749 StringData = 0;
750 }
751
752 bool is(TokenKind K) const { return Kind == K; }
753
754 SourceLocation getLocation() const {
755 return SourceLocation::getFromRawEncoding(Location);
756 }
757
758 StringRef getString() const {
759 return StringRef(StringData, StringLength);
760 }
761 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000762
763 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000764 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000765 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000766
767 /// \brief Whether this is a system module.
768 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000769
770 /// \brief Whether this is an exhaustive set of configuration macros.
771 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000772 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000773
Douglas Gregor82e52372012-11-06 19:39:40 +0000774
Douglas Gregora30cfe52011-11-11 19:10:28 +0000775 class ModuleMapParser {
776 Lexer &L;
777 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000778
779 /// \brief Default target information, used only for string literal
780 /// parsing.
781 const TargetInfo *Target;
782
Douglas Gregora30cfe52011-11-11 19:10:28 +0000783 DiagnosticsEngine &Diags;
784 ModuleMap &Map;
785
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000786 /// \brief The directory that this module map resides in.
787 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000788
789 /// \brief The directory containing Clang-supplied headers.
790 const DirectoryEntry *BuiltinIncludeDir;
791
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000792 /// \brief Whether this module map is in a system header directory.
793 bool IsSystem;
794
Douglas Gregora30cfe52011-11-11 19:10:28 +0000795 /// \brief Whether an error occurred.
796 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000797
Douglas Gregora30cfe52011-11-11 19:10:28 +0000798 /// \brief Stores string data for the various string literals referenced
799 /// during parsing.
800 llvm::BumpPtrAllocator StringData;
801
802 /// \brief The current token.
803 MMToken Tok;
804
805 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000806 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000807
808 /// \brief Consume the current token and return its location.
809 SourceLocation consumeToken();
810
811 /// \brief Skip tokens until we reach the a token with the given kind
812 /// (or the end of the file).
813 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000814
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000815 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000816 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000817 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000818 void parseRequiresDecl();
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000819 void parseHeaderDecl(clang::MMToken::TokenKind,
820 SourceLocation LeadingLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000821 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000822 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000823 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000824 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000825 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000826 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000827 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000828
Douglas Gregor6a1db482011-12-09 02:04:43 +0000829 const DirectoryEntry *getOverriddenHeaderSearchDir();
830
Douglas Gregora30cfe52011-11-11 19:10:28 +0000831 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000832 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000833 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000834 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000835 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000836 const DirectoryEntry *Directory,
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000837 const DirectoryEntry *BuiltinIncludeDir,
838 bool IsSystem)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000839 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000840 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
841 IsSystem(IsSystem), HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000842 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000843 Tok.clear();
844 consumeToken();
845 }
846
847 bool parseModuleMapFile();
848 };
849}
850
851SourceLocation ModuleMapParser::consumeToken() {
852retry:
853 SourceLocation Result = Tok.getLocation();
854 Tok.clear();
855
856 Token LToken;
857 L.LexFromRawLexer(LToken);
858 Tok.Location = LToken.getLocation().getRawEncoding();
859 switch (LToken.getKind()) {
860 case tok::raw_identifier:
861 Tok.StringData = LToken.getRawIdentifierData();
862 Tok.StringLength = LToken.getLength();
863 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000864 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000865 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000866 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000867 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000868 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000869 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000870 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000871 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000872 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000873 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000874 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000875 .Case("umbrella", MMToken::UmbrellaKeyword)
876 .Default(MMToken::Identifier);
877 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000878
879 case tok::comma:
880 Tok.Kind = MMToken::Comma;
881 break;
882
Douglas Gregora30cfe52011-11-11 19:10:28 +0000883 case tok::eof:
884 Tok.Kind = MMToken::EndOfFile;
885 break;
886
887 case tok::l_brace:
888 Tok.Kind = MMToken::LBrace;
889 break;
890
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000891 case tok::l_square:
892 Tok.Kind = MMToken::LSquare;
893 break;
894
Douglas Gregor90db2602011-12-02 01:47:07 +0000895 case tok::period:
896 Tok.Kind = MMToken::Period;
897 break;
898
Douglas Gregora30cfe52011-11-11 19:10:28 +0000899 case tok::r_brace:
900 Tok.Kind = MMToken::RBrace;
901 break;
902
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000903 case tok::r_square:
904 Tok.Kind = MMToken::RSquare;
905 break;
906
Douglas Gregor90db2602011-12-02 01:47:07 +0000907 case tok::star:
908 Tok.Kind = MMToken::Star;
909 break;
910
Douglas Gregora30cfe52011-11-11 19:10:28 +0000911 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000912 if (LToken.hasUDSuffix()) {
913 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
914 HadError = true;
915 goto retry;
916 }
917
Douglas Gregora30cfe52011-11-11 19:10:28 +0000918 // Parse the string literal.
919 LangOptions LangOpts;
920 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
921 if (StringLiteral.hadError)
922 goto retry;
923
924 // Copy the string literal into our string data allocator.
925 unsigned Length = StringLiteral.GetStringLength();
926 char *Saved = StringData.Allocate<char>(Length + 1);
927 memcpy(Saved, StringLiteral.GetString().data(), Length);
928 Saved[Length] = 0;
929
930 // Form the token.
931 Tok.Kind = MMToken::StringLiteral;
932 Tok.StringData = Saved;
933 Tok.StringLength = Length;
934 break;
935 }
936
937 case tok::comment:
938 goto retry;
939
940 default:
941 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
942 HadError = true;
943 goto retry;
944 }
945
946 return Result;
947}
948
949void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
950 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000951 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000952 do {
953 switch (Tok.Kind) {
954 case MMToken::EndOfFile:
955 return;
956
957 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000958 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000959 return;
960
961 ++braceDepth;
962 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000963
964 case MMToken::LSquare:
965 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
966 return;
967
968 ++squareDepth;
969 break;
970
Douglas Gregora30cfe52011-11-11 19:10:28 +0000971 case MMToken::RBrace:
972 if (braceDepth > 0)
973 --braceDepth;
974 else if (Tok.is(K))
975 return;
976 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000977
978 case MMToken::RSquare:
979 if (squareDepth > 0)
980 --squareDepth;
981 else if (Tok.is(K))
982 return;
983 break;
984
Douglas Gregora30cfe52011-11-11 19:10:28 +0000985 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000986 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000987 return;
988 break;
989 }
990
991 consumeToken();
992 } while (true);
993}
994
Douglas Gregor587986e2011-12-07 02:23:45 +0000995/// \brief Parse a module-id.
996///
997/// module-id:
998/// identifier
999/// identifier '.' module-id
1000///
1001/// \returns true if an error occurred, false otherwise.
1002bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1003 Id.clear();
1004 do {
1005 if (Tok.is(MMToken::Identifier)) {
1006 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1007 consumeToken();
1008 } else {
1009 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1010 return true;
1011 }
1012
1013 if (!Tok.is(MMToken::Period))
1014 break;
1015
1016 consumeToken();
1017 } while (true);
1018
1019 return false;
1020}
1021
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001022namespace {
1023 /// \brief Enumerates the known attributes.
1024 enum AttributeKind {
1025 /// \brief An unknown attribute.
1026 AT_unknown,
1027 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001028 AT_system,
1029 /// \brief The 'exhaustive' attribute.
1030 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001031 };
1032}
1033
Douglas Gregora30cfe52011-11-11 19:10:28 +00001034/// \brief Parse a module declaration.
1035///
1036/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001037/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1038/// { module-member* }
1039///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001040/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001041/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001042/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001043/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001044/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001045/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001046///
1047/// submodule-declaration:
1048/// module-declaration
1049/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001050void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001051 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1052 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +00001053 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001054 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001055 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001056 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001057
Douglas Gregord620a842011-12-06 17:16:41 +00001058 // Parse 'explicit' keyword, if present.
1059 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001060 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001061 Explicit = true;
1062 }
1063
1064 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001065 if (Tok.is(MMToken::FrameworkKeyword)) {
1066 consumeToken();
1067 Framework = true;
1068 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001069
1070 // Parse 'module' keyword.
1071 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001072 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001073 consumeToken();
1074 HadError = true;
1075 return;
1076 }
1077 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001078
1079 // If we have a wildcard for the module name, this is an inferred submodule.
1080 // Parse it.
1081 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001082 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001083
1084 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001085 ModuleId Id;
1086 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001087 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001088 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001089 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001090
Douglas Gregor587986e2011-12-07 02:23:45 +00001091 if (ActiveModule) {
1092 if (Id.size() > 1) {
1093 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1094 << SourceRange(Id.front().second, Id.back().second);
1095
1096 HadError = true;
1097 return;
1098 }
1099 } else if (Id.size() == 1 && Explicit) {
1100 // Top-level modules can't be explicit.
1101 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1102 Explicit = false;
1103 ExplicitLoc = SourceLocation();
1104 HadError = true;
1105 }
1106
1107 Module *PreviousActiveModule = ActiveModule;
1108 if (Id.size() > 1) {
1109 // This module map defines a submodule. Go find the module of which it
1110 // is a submodule.
1111 ActiveModule = 0;
1112 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1113 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1114 ActiveModule = Next;
1115 continue;
1116 }
1117
1118 if (ActiveModule) {
1119 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1120 << Id[I].first << ActiveModule->getTopLevelModule();
1121 } else {
1122 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1123 }
1124 HadError = true;
1125 return;
1126 }
1127 }
1128
1129 StringRef ModuleName = Id.back().first;
1130 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001131
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001132 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001133 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001134 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001135
Douglas Gregora30cfe52011-11-11 19:10:28 +00001136 // Parse the opening brace.
1137 if (!Tok.is(MMToken::LBrace)) {
1138 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1139 << ModuleName;
1140 HadError = true;
1141 return;
1142 }
1143 SourceLocation LBraceLoc = consumeToken();
1144
1145 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001146 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001147 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1148 // Skip the module definition.
1149 skipUntil(MMToken::RBrace);
1150 if (Tok.is(MMToken::RBrace))
1151 consumeToken();
1152 else {
1153 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1154 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1155 HadError = true;
1156 }
1157 return;
1158 }
1159
Douglas Gregora30cfe52011-11-11 19:10:28 +00001160 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1161 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001162 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001163
1164 // Skip the module definition.
1165 skipUntil(MMToken::RBrace);
1166 if (Tok.is(MMToken::RBrace))
1167 consumeToken();
1168
1169 HadError = true;
1170 return;
1171 }
1172
1173 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001174 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1175 Explicit).first;
1176 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001177 if (Attrs.IsSystem || IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001178 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001179
1180 bool Done = false;
1181 do {
1182 switch (Tok.Kind) {
1183 case MMToken::EndOfFile:
1184 case MMToken::RBrace:
1185 Done = true;
1186 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001187
1188 case MMToken::ConfigMacros:
1189 parseConfigMacros();
1190 break;
1191
Douglas Gregor906d66a2013-03-20 21:10:35 +00001192 case MMToken::Conflict:
1193 parseConflict();
1194 break;
1195
Douglas Gregora30cfe52011-11-11 19:10:28 +00001196 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001197 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001198 case MMToken::ModuleKeyword:
1199 parseModuleDecl();
1200 break;
1201
Douglas Gregor90db2602011-12-02 01:47:07 +00001202 case MMToken::ExportKeyword:
1203 parseExportDecl();
1204 break;
1205
Douglas Gregor51f564f2011-12-31 04:05:44 +00001206 case MMToken::RequiresKeyword:
1207 parseRequiresDecl();
1208 break;
1209
Douglas Gregor77d029f2011-12-08 19:11:24 +00001210 case MMToken::UmbrellaKeyword: {
1211 SourceLocation UmbrellaLoc = consumeToken();
1212 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001213 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +00001214 else
1215 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001216 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001217 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001218
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001219 case MMToken::ExcludeKeyword: {
1220 SourceLocation ExcludeLoc = consumeToken();
1221 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001222 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001223 } else {
1224 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1225 << "exclude";
1226 }
1227 break;
1228 }
1229
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001230 case MMToken::PrivateKeyword: {
1231 SourceLocation PrivateLoc = consumeToken();
1232 if (Tok.is(MMToken::HeaderKeyword)) {
1233 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1234 } else {
1235 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1236 << "private";
1237 }
1238 break;
1239 }
1240
Douglas Gregor489ad432011-12-08 18:00:48 +00001241 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001242 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001243 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001244
1245 case MMToken::LinkKeyword:
1246 parseLinkDecl();
1247 break;
1248
Douglas Gregora30cfe52011-11-11 19:10:28 +00001249 default:
1250 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1251 consumeToken();
1252 break;
1253 }
1254 } while (!Done);
1255
1256 if (Tok.is(MMToken::RBrace))
1257 consumeToken();
1258 else {
1259 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1260 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1261 HadError = true;
1262 }
1263
Douglas Gregor8767dc22013-01-14 17:57:51 +00001264 // If the active module is a top-level framework, and there are no link
1265 // libraries, automatically link against the framework.
1266 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1267 ActiveModule->LinkLibraries.empty()) {
1268 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1269 }
1270
Douglas Gregor587986e2011-12-07 02:23:45 +00001271 // We're done parsing this module. Pop back to the previous module.
1272 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001273}
Douglas Gregord620a842011-12-06 17:16:41 +00001274
Douglas Gregor51f564f2011-12-31 04:05:44 +00001275/// \brief Parse a requires declaration.
1276///
1277/// requires-declaration:
1278/// 'requires' feature-list
1279///
1280/// feature-list:
1281/// identifier ',' feature-list
1282/// identifier
1283void ModuleMapParser::parseRequiresDecl() {
1284 assert(Tok.is(MMToken::RequiresKeyword));
1285
1286 // Parse 'requires' keyword.
1287 consumeToken();
1288
1289 // Parse the feature-list.
1290 do {
1291 if (!Tok.is(MMToken::Identifier)) {
1292 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1293 HadError = true;
1294 return;
1295 }
1296
1297 // Consume the feature name.
1298 std::string Feature = Tok.getString();
1299 consumeToken();
1300
1301 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001302 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001303
1304 if (!Tok.is(MMToken::Comma))
1305 break;
1306
1307 // Consume the comma.
1308 consumeToken();
1309 } while (true);
1310}
1311
Douglas Gregord620a842011-12-06 17:16:41 +00001312/// \brief Append to \p Paths the set of paths needed to get to the
1313/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001314static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001315 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001316 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001317 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001318 for (; Mod; Mod = Mod->Parent) {
1319 if (Mod->IsFramework)
1320 Paths.push_back(Mod->Name);
1321 }
1322
1323 if (Paths.empty())
1324 return;
1325
1326 // Add Frameworks/Name.framework for each subframework.
1327 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1328 llvm::sys::path::append(Path, "Frameworks");
1329 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1330 }
1331}
1332
Douglas Gregora30cfe52011-11-11 19:10:28 +00001333/// \brief Parse a header declaration.
1334///
1335/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001336/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001337/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001338void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1339 SourceLocation LeadingLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001340 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001341 consumeToken();
1342
Douglas Gregora30cfe52011-11-11 19:10:28 +00001343 // Parse the header name.
1344 if (!Tok.is(MMToken::StringLiteral)) {
1345 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1346 << "header";
1347 HadError = true;
1348 return;
1349 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001350 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001351 SourceLocation FileNameLoc = consumeToken();
1352
Douglas Gregor77d029f2011-12-08 19:11:24 +00001353 // Check whether we already have an umbrella.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001354 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Douglas Gregor77d029f2011-12-08 19:11:24 +00001355 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1356 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001357 HadError = true;
1358 return;
1359 }
1360
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001361 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001362 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001363 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001364 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001365 if (llvm::sys::path::is_absolute(FileName)) {
1366 PathName = FileName;
1367 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001368 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1369 PathName = Dir->getName();
1370 llvm::sys::path::append(PathName, FileName);
1371 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001372 } else {
1373 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001374 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001375 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001376
Douglas Gregord620a842011-12-06 17:16:41 +00001377 if (ActiveModule->isPartOfFramework()) {
1378 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001379
1380 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001381 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001382 llvm::sys::path::append(PathName, FileName);
1383 File = SourceMgr.getFileManager().getFile(PathName);
1384
1385 if (!File) {
1386 // Check whether this file is in the private headers.
1387 PathName.resize(PathLength);
1388 llvm::sys::path::append(PathName, "PrivateHeaders");
1389 llvm::sys::path::append(PathName, FileName);
1390 File = SourceMgr.getFileManager().getFile(PathName);
1391 }
1392 } else {
1393 // Lookup for normal headers.
1394 llvm::sys::path::append(PathName, FileName);
1395 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001396
1397 // If this is a system module with a top-level header, this header
1398 // may have a counterpart (or replacement) in the set of headers
1399 // supplied by Clang. Find that builtin header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001400 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1401 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1402 isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001403 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001404 llvm::sys::path::append(BuiltinPathName, FileName);
1405 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1406
1407 // If Clang supplies this header but the underlying system does not,
1408 // just silently swap in our builtin version. Otherwise, we'll end
1409 // up adding both (later).
1410 if (!File && BuiltinFile) {
1411 File = BuiltinFile;
1412 BuiltinFile = 0;
1413 }
1414 }
Douglas Gregord620a842011-12-06 17:16:41 +00001415 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001416 }
Douglas Gregora8654052011-11-17 22:09:43 +00001417
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001418 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1419 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001420 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001421 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001422 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001423 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001424 HadError = true;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001425 } else if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001426 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001427 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001428 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001429 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001430 HadError = true;
1431 } else {
1432 // Record this umbrella header.
1433 Map.setUmbrellaHeader(ActiveModule, File);
1434 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001435 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001436 // Record this header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001437 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1438 if (LeadingToken == MMToken::ExcludeKeyword)
1439 Role = ModuleMap::ExcludedHeader;
1440 else if (LeadingToken == MMToken::PrivateKeyword)
1441 Role = ModuleMap::PrivateHeader;
1442 else
1443 assert(LeadingToken == MMToken::HeaderKeyword);
1444
1445 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001446
1447 // If there is a builtin counterpart to this file, add it now.
1448 if (BuiltinFile)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001449 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001450 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001451 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor71f49f52012-11-15 19:47:16 +00001452 // Ignore excluded header files. They're optional anyway.
1453
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001454 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001455 << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001456 HadError = true;
1457 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001458}
1459
Douglas Gregor77d029f2011-12-08 19:11:24 +00001460/// \brief Parse an umbrella directory declaration.
1461///
1462/// umbrella-dir-declaration:
1463/// umbrella string-literal
1464void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1465 // Parse the directory name.
1466 if (!Tok.is(MMToken::StringLiteral)) {
1467 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1468 << "umbrella";
1469 HadError = true;
1470 return;
1471 }
1472
1473 std::string DirName = Tok.getString();
1474 SourceLocation DirNameLoc = consumeToken();
1475
1476 // Check whether we already have an umbrella.
1477 if (ActiveModule->Umbrella) {
1478 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1479 << ActiveModule->getFullModuleName();
1480 HadError = true;
1481 return;
1482 }
1483
1484 // Look for this file.
1485 const DirectoryEntry *Dir = 0;
1486 if (llvm::sys::path::is_absolute(DirName))
1487 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1488 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001489 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001490 PathName = Directory->getName();
1491 llvm::sys::path::append(PathName, DirName);
1492 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1493 }
1494
1495 if (!Dir) {
1496 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1497 << DirName;
1498 HadError = true;
1499 return;
1500 }
1501
1502 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1503 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1504 << OwningModule->getFullModuleName();
1505 HadError = true;
1506 return;
1507 }
1508
1509 // Record this umbrella directory.
1510 Map.setUmbrellaDir(ActiveModule, Dir);
1511}
1512
Douglas Gregor90db2602011-12-02 01:47:07 +00001513/// \brief Parse a module export declaration.
1514///
1515/// export-declaration:
1516/// 'export' wildcard-module-id
1517///
1518/// wildcard-module-id:
1519/// identifier
1520/// '*'
1521/// identifier '.' wildcard-module-id
1522void ModuleMapParser::parseExportDecl() {
1523 assert(Tok.is(MMToken::ExportKeyword));
1524 SourceLocation ExportLoc = consumeToken();
1525
1526 // Parse the module-id with an optional wildcard at the end.
1527 ModuleId ParsedModuleId;
1528 bool Wildcard = false;
1529 do {
1530 if (Tok.is(MMToken::Identifier)) {
1531 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1532 Tok.getLocation()));
1533 consumeToken();
1534
1535 if (Tok.is(MMToken::Period)) {
1536 consumeToken();
1537 continue;
1538 }
1539
1540 break;
1541 }
1542
1543 if(Tok.is(MMToken::Star)) {
1544 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001545 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001546 break;
1547 }
1548
1549 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1550 HadError = true;
1551 return;
1552 } while (true);
1553
1554 Module::UnresolvedExportDecl Unresolved = {
1555 ExportLoc, ParsedModuleId, Wildcard
1556 };
1557 ActiveModule->UnresolvedExports.push_back(Unresolved);
1558}
1559
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001560/// \brief Parse a link declaration.
1561///
1562/// module-declaration:
1563/// 'link' 'framework'[opt] string-literal
1564void ModuleMapParser::parseLinkDecl() {
1565 assert(Tok.is(MMToken::LinkKeyword));
1566 SourceLocation LinkLoc = consumeToken();
1567
1568 // Parse the optional 'framework' keyword.
1569 bool IsFramework = false;
1570 if (Tok.is(MMToken::FrameworkKeyword)) {
1571 consumeToken();
1572 IsFramework = true;
1573 }
1574
1575 // Parse the library name
1576 if (!Tok.is(MMToken::StringLiteral)) {
1577 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1578 << IsFramework << SourceRange(LinkLoc);
1579 HadError = true;
1580 return;
1581 }
1582
1583 std::string LibraryName = Tok.getString();
1584 consumeToken();
1585 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1586 IsFramework));
1587}
1588
Douglas Gregor63a72682013-03-20 00:22:05 +00001589/// \brief Parse a configuration macro declaration.
1590///
1591/// module-declaration:
1592/// 'config_macros' attributes[opt] config-macro-list?
1593///
1594/// config-macro-list:
1595/// identifier (',' identifier)?
1596void ModuleMapParser::parseConfigMacros() {
1597 assert(Tok.is(MMToken::ConfigMacros));
1598 SourceLocation ConfigMacrosLoc = consumeToken();
1599
1600 // Only top-level modules can have configuration macros.
1601 if (ActiveModule->Parent) {
1602 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1603 }
1604
1605 // Parse the optional attributes.
1606 Attributes Attrs;
1607 parseOptionalAttributes(Attrs);
1608 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1609 ActiveModule->ConfigMacrosExhaustive = true;
1610 }
1611
1612 // If we don't have an identifier, we're done.
1613 if (!Tok.is(MMToken::Identifier))
1614 return;
1615
1616 // Consume the first identifier.
1617 if (!ActiveModule->Parent) {
1618 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1619 }
1620 consumeToken();
1621
1622 do {
1623 // If there's a comma, consume it.
1624 if (!Tok.is(MMToken::Comma))
1625 break;
1626 consumeToken();
1627
1628 // We expect to see a macro name here.
1629 if (!Tok.is(MMToken::Identifier)) {
1630 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1631 break;
1632 }
1633
1634 // Consume the macro name.
1635 if (!ActiveModule->Parent) {
1636 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1637 }
1638 consumeToken();
1639 } while (true);
1640}
1641
Douglas Gregor906d66a2013-03-20 21:10:35 +00001642/// \brief Format a module-id into a string.
1643static std::string formatModuleId(const ModuleId &Id) {
1644 std::string result;
1645 {
1646 llvm::raw_string_ostream OS(result);
1647
1648 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1649 if (I)
1650 OS << ".";
1651 OS << Id[I].first;
1652 }
1653 }
1654
1655 return result;
1656}
1657
1658/// \brief Parse a conflict declaration.
1659///
1660/// module-declaration:
1661/// 'conflict' module-id ',' string-literal
1662void ModuleMapParser::parseConflict() {
1663 assert(Tok.is(MMToken::Conflict));
1664 SourceLocation ConflictLoc = consumeToken();
1665 Module::UnresolvedConflict Conflict;
1666
1667 // Parse the module-id.
1668 if (parseModuleId(Conflict.Id))
1669 return;
1670
1671 // Parse the ','.
1672 if (!Tok.is(MMToken::Comma)) {
1673 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1674 << SourceRange(ConflictLoc);
1675 return;
1676 }
1677 consumeToken();
1678
1679 // Parse the message.
1680 if (!Tok.is(MMToken::StringLiteral)) {
1681 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1682 << formatModuleId(Conflict.Id);
1683 return;
1684 }
1685 Conflict.Message = Tok.getString().str();
1686 consumeToken();
1687
1688 // Add this unresolved conflict.
1689 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1690}
1691
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001692/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001693///
1694/// module-declaration:
1695/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1696/// { inferred-module-member* }
1697///
1698/// inferred-module-member:
1699/// 'export' '*'
1700/// 'exclude' identifier
1701void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001702 assert(Tok.is(MMToken::Star));
1703 SourceLocation StarLoc = consumeToken();
1704 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001705
Douglas Gregor1e123682011-12-05 22:27:44 +00001706 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001707 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001708 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1709 Failed = true;
1710 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001711
1712 if (ActiveModule) {
1713 // Inferred modules must have umbrella directories.
1714 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1715 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1716 Failed = true;
1717 }
1718
1719 // Check for redefinition of an inferred module.
1720 if (!Failed && ActiveModule->InferSubmodules) {
1721 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1722 if (ActiveModule->InferredSubmoduleLoc.isValid())
1723 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1724 diag::note_mmap_prev_definition);
1725 Failed = true;
1726 }
1727
1728 // Check for the 'framework' keyword, which is not permitted here.
1729 if (Framework) {
1730 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1731 Framework = false;
1732 }
1733 } else if (Explicit) {
1734 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1735 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001736 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001737
Douglas Gregor1e123682011-12-05 22:27:44 +00001738 // If there were any problems with this inferred submodule, skip its body.
1739 if (Failed) {
1740 if (Tok.is(MMToken::LBrace)) {
1741 consumeToken();
1742 skipUntil(MMToken::RBrace);
1743 if (Tok.is(MMToken::RBrace))
1744 consumeToken();
1745 }
1746 HadError = true;
1747 return;
1748 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001749
1750 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001751 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001752 parseOptionalAttributes(Attrs);
1753
1754 if (ActiveModule) {
1755 // Note that we have an inferred submodule.
1756 ActiveModule->InferSubmodules = true;
1757 ActiveModule->InferredSubmoduleLoc = StarLoc;
1758 ActiveModule->InferExplicitSubmodules = Explicit;
1759 } else {
1760 // We'll be inferring framework modules for this directory.
1761 Map.InferredDirectories[Directory].InferModules = true;
1762 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1763 }
1764
Douglas Gregor1e123682011-12-05 22:27:44 +00001765 // Parse the opening brace.
1766 if (!Tok.is(MMToken::LBrace)) {
1767 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1768 HadError = true;
1769 return;
1770 }
1771 SourceLocation LBraceLoc = consumeToken();
1772
1773 // Parse the body of the inferred submodule.
1774 bool Done = false;
1775 do {
1776 switch (Tok.Kind) {
1777 case MMToken::EndOfFile:
1778 case MMToken::RBrace:
1779 Done = true;
1780 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001781
1782 case MMToken::ExcludeKeyword: {
1783 if (ActiveModule) {
1784 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001785 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001786 consumeToken();
1787 break;
1788 }
1789
1790 consumeToken();
1791 if (!Tok.is(MMToken::Identifier)) {
1792 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1793 break;
1794 }
1795
1796 Map.InferredDirectories[Directory].ExcludedModules
1797 .push_back(Tok.getString());
1798 consumeToken();
1799 break;
1800 }
1801
1802 case MMToken::ExportKeyword:
1803 if (!ActiveModule) {
1804 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001805 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001806 consumeToken();
1807 break;
1808 }
1809
Douglas Gregor1e123682011-12-05 22:27:44 +00001810 consumeToken();
1811 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001812 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001813 else
1814 Diags.Report(Tok.getLocation(),
1815 diag::err_mmap_expected_export_wildcard);
1816 consumeToken();
1817 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001818
Douglas Gregor1e123682011-12-05 22:27:44 +00001819 case MMToken::ExplicitKeyword:
1820 case MMToken::ModuleKeyword:
1821 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001822 case MMToken::PrivateKeyword:
Douglas Gregor1e123682011-12-05 22:27:44 +00001823 case MMToken::UmbrellaKeyword:
1824 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001825 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001826 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001827 consumeToken();
1828 break;
1829 }
1830 } while (!Done);
1831
1832 if (Tok.is(MMToken::RBrace))
1833 consumeToken();
1834 else {
1835 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1836 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1837 HadError = true;
1838 }
1839}
1840
Douglas Gregor82e52372012-11-06 19:39:40 +00001841/// \brief Parse optional attributes.
1842///
1843/// attributes:
1844/// attribute attributes
1845/// attribute
1846///
1847/// attribute:
1848/// [ identifier ]
1849///
1850/// \param Attrs Will be filled in with the parsed attributes.
1851///
1852/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001853bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001854 bool HadError = false;
1855
1856 while (Tok.is(MMToken::LSquare)) {
1857 // Consume the '['.
1858 SourceLocation LSquareLoc = consumeToken();
1859
1860 // Check whether we have an attribute name here.
1861 if (!Tok.is(MMToken::Identifier)) {
1862 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1863 skipUntil(MMToken::RSquare);
1864 if (Tok.is(MMToken::RSquare))
1865 consumeToken();
1866 HadError = true;
1867 }
1868
1869 // Decode the attribute name.
1870 AttributeKind Attribute
1871 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001872 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00001873 .Case("system", AT_system)
1874 .Default(AT_unknown);
1875 switch (Attribute) {
1876 case AT_unknown:
1877 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1878 << Tok.getString();
1879 break;
1880
1881 case AT_system:
1882 Attrs.IsSystem = true;
1883 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001884
1885 case AT_exhaustive:
1886 Attrs.IsExhaustive = true;
1887 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001888 }
1889 consumeToken();
1890
1891 // Consume the ']'.
1892 if (!Tok.is(MMToken::RSquare)) {
1893 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1894 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1895 skipUntil(MMToken::RSquare);
1896 HadError = true;
1897 }
1898
1899 if (Tok.is(MMToken::RSquare))
1900 consumeToken();
1901 }
1902
1903 return HadError;
1904}
1905
Douglas Gregor6a1db482011-12-09 02:04:43 +00001906/// \brief If there is a specific header search directory due the presence
1907/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1908const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1909 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1910 // If we have an umbrella directory, use that.
1911 if (Mod->hasUmbrellaDir())
1912 return Mod->getUmbrellaDir();
1913
1914 // If we have a framework directory, stop looking.
1915 if (Mod->IsFramework)
1916 return 0;
1917 }
1918
1919 return 0;
1920}
1921
Douglas Gregora30cfe52011-11-11 19:10:28 +00001922/// \brief Parse a module map file.
1923///
1924/// module-map-file:
1925/// module-declaration*
1926bool ModuleMapParser::parseModuleMapFile() {
1927 do {
1928 switch (Tok.Kind) {
1929 case MMToken::EndOfFile:
1930 return HadError;
1931
Douglas Gregor587986e2011-12-07 02:23:45 +00001932 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001933 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001934 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001935 parseModuleDecl();
1936 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001937
Douglas Gregor51f564f2011-12-31 04:05:44 +00001938 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00001939 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00001940 case MMToken::Conflict:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001941 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001942 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001943 case MMToken::HeaderKeyword:
1944 case MMToken::Identifier:
1945 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001946 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001947 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001948 case MMToken::Period:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001949 case MMToken::PrivateKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001950 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001951 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001952 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001953 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001954 case MMToken::StringLiteral:
1955 case MMToken::UmbrellaKeyword:
1956 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1957 HadError = true;
1958 consumeToken();
1959 break;
1960 }
1961 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001962}
1963
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001964bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001965 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1966 = ParsedModuleMap.find(File);
1967 if (Known != ParsedModuleMap.end())
1968 return Known->second;
1969
Douglas Gregordc58aa72012-01-30 06:01:29 +00001970 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001971 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1972 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1973 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001974 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001975
1976 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001977 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1978 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001979 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001980 BuiltinIncludeDir, IsSystem);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001981 bool Result = Parser.parseModuleMapFile();
1982 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001983 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001984 return Result;
1985}