blob: f46a87abc97ee1c5ce226d134a3db9e785e657df [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)) {
479 parseModuleMapFile(ModMapFile);
480 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 Gregora30cfe52011-11-11 19:10:28 +0000792 /// \brief Whether an error occurred.
793 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000794
Douglas Gregora30cfe52011-11-11 19:10:28 +0000795 /// \brief Stores string data for the various string literals referenced
796 /// during parsing.
797 llvm::BumpPtrAllocator StringData;
798
799 /// \brief The current token.
800 MMToken Tok;
801
802 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000803 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000804
805 /// \brief Consume the current token and return its location.
806 SourceLocation consumeToken();
807
808 /// \brief Skip tokens until we reach the a token with the given kind
809 /// (or the end of the file).
810 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000811
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000812 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000813 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000814 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000815 void parseRequiresDecl();
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000816 void parseHeaderDecl(clang::MMToken::TokenKind,
817 SourceLocation LeadingLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000818 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000819 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000820 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000821 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000822 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000823 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000824 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000825
Douglas Gregor6a1db482011-12-09 02:04:43 +0000826 const DirectoryEntry *getOverriddenHeaderSearchDir();
827
Douglas Gregora30cfe52011-11-11 19:10:28 +0000828 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000829 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000830 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000831 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000832 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000833 const DirectoryEntry *Directory,
834 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000835 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000836 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
837 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000838 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000839 Tok.clear();
840 consumeToken();
841 }
842
843 bool parseModuleMapFile();
844 };
845}
846
847SourceLocation ModuleMapParser::consumeToken() {
848retry:
849 SourceLocation Result = Tok.getLocation();
850 Tok.clear();
851
852 Token LToken;
853 L.LexFromRawLexer(LToken);
854 Tok.Location = LToken.getLocation().getRawEncoding();
855 switch (LToken.getKind()) {
856 case tok::raw_identifier:
857 Tok.StringData = LToken.getRawIdentifierData();
858 Tok.StringLength = LToken.getLength();
859 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000860 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000861 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000862 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000863 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000864 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000865 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000866 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000867 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000868 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000869 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000870 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000871 .Case("umbrella", MMToken::UmbrellaKeyword)
872 .Default(MMToken::Identifier);
873 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000874
875 case tok::comma:
876 Tok.Kind = MMToken::Comma;
877 break;
878
Douglas Gregora30cfe52011-11-11 19:10:28 +0000879 case tok::eof:
880 Tok.Kind = MMToken::EndOfFile;
881 break;
882
883 case tok::l_brace:
884 Tok.Kind = MMToken::LBrace;
885 break;
886
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000887 case tok::l_square:
888 Tok.Kind = MMToken::LSquare;
889 break;
890
Douglas Gregor90db2602011-12-02 01:47:07 +0000891 case tok::period:
892 Tok.Kind = MMToken::Period;
893 break;
894
Douglas Gregora30cfe52011-11-11 19:10:28 +0000895 case tok::r_brace:
896 Tok.Kind = MMToken::RBrace;
897 break;
898
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000899 case tok::r_square:
900 Tok.Kind = MMToken::RSquare;
901 break;
902
Douglas Gregor90db2602011-12-02 01:47:07 +0000903 case tok::star:
904 Tok.Kind = MMToken::Star;
905 break;
906
Douglas Gregora30cfe52011-11-11 19:10:28 +0000907 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000908 if (LToken.hasUDSuffix()) {
909 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
910 HadError = true;
911 goto retry;
912 }
913
Douglas Gregora30cfe52011-11-11 19:10:28 +0000914 // Parse the string literal.
915 LangOptions LangOpts;
916 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
917 if (StringLiteral.hadError)
918 goto retry;
919
920 // Copy the string literal into our string data allocator.
921 unsigned Length = StringLiteral.GetStringLength();
922 char *Saved = StringData.Allocate<char>(Length + 1);
923 memcpy(Saved, StringLiteral.GetString().data(), Length);
924 Saved[Length] = 0;
925
926 // Form the token.
927 Tok.Kind = MMToken::StringLiteral;
928 Tok.StringData = Saved;
929 Tok.StringLength = Length;
930 break;
931 }
932
933 case tok::comment:
934 goto retry;
935
936 default:
937 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
938 HadError = true;
939 goto retry;
940 }
941
942 return Result;
943}
944
945void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
946 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000947 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000948 do {
949 switch (Tok.Kind) {
950 case MMToken::EndOfFile:
951 return;
952
953 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000954 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000955 return;
956
957 ++braceDepth;
958 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000959
960 case MMToken::LSquare:
961 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
962 return;
963
964 ++squareDepth;
965 break;
966
Douglas Gregora30cfe52011-11-11 19:10:28 +0000967 case MMToken::RBrace:
968 if (braceDepth > 0)
969 --braceDepth;
970 else if (Tok.is(K))
971 return;
972 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000973
974 case MMToken::RSquare:
975 if (squareDepth > 0)
976 --squareDepth;
977 else if (Tok.is(K))
978 return;
979 break;
980
Douglas Gregora30cfe52011-11-11 19:10:28 +0000981 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000982 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000983 return;
984 break;
985 }
986
987 consumeToken();
988 } while (true);
989}
990
Douglas Gregor587986e2011-12-07 02:23:45 +0000991/// \brief Parse a module-id.
992///
993/// module-id:
994/// identifier
995/// identifier '.' module-id
996///
997/// \returns true if an error occurred, false otherwise.
998bool ModuleMapParser::parseModuleId(ModuleId &Id) {
999 Id.clear();
1000 do {
1001 if (Tok.is(MMToken::Identifier)) {
1002 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1003 consumeToken();
1004 } else {
1005 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1006 return true;
1007 }
1008
1009 if (!Tok.is(MMToken::Period))
1010 break;
1011
1012 consumeToken();
1013 } while (true);
1014
1015 return false;
1016}
1017
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001018namespace {
1019 /// \brief Enumerates the known attributes.
1020 enum AttributeKind {
1021 /// \brief An unknown attribute.
1022 AT_unknown,
1023 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001024 AT_system,
1025 /// \brief The 'exhaustive' attribute.
1026 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001027 };
1028}
1029
Douglas Gregora30cfe52011-11-11 19:10:28 +00001030/// \brief Parse a module declaration.
1031///
1032/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001033/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1034/// { module-member* }
1035///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001036/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001037/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001038/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001039/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001040/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001041/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001042///
1043/// submodule-declaration:
1044/// module-declaration
1045/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001046void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001047 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1048 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +00001049 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001050 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001051 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001052 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001053
Douglas Gregord620a842011-12-06 17:16:41 +00001054 // Parse 'explicit' keyword, if present.
1055 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001056 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001057 Explicit = true;
1058 }
1059
1060 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001061 if (Tok.is(MMToken::FrameworkKeyword)) {
1062 consumeToken();
1063 Framework = true;
1064 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001065
1066 // Parse 'module' keyword.
1067 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001068 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001069 consumeToken();
1070 HadError = true;
1071 return;
1072 }
1073 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001074
1075 // If we have a wildcard for the module name, this is an inferred submodule.
1076 // Parse it.
1077 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001078 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001079
1080 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001081 ModuleId Id;
1082 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001083 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001084 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001085 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001086
Douglas Gregor587986e2011-12-07 02:23:45 +00001087 if (ActiveModule) {
1088 if (Id.size() > 1) {
1089 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1090 << SourceRange(Id.front().second, Id.back().second);
1091
1092 HadError = true;
1093 return;
1094 }
1095 } else if (Id.size() == 1 && Explicit) {
1096 // Top-level modules can't be explicit.
1097 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1098 Explicit = false;
1099 ExplicitLoc = SourceLocation();
1100 HadError = true;
1101 }
1102
1103 Module *PreviousActiveModule = ActiveModule;
1104 if (Id.size() > 1) {
1105 // This module map defines a submodule. Go find the module of which it
1106 // is a submodule.
1107 ActiveModule = 0;
1108 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1109 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1110 ActiveModule = Next;
1111 continue;
1112 }
1113
1114 if (ActiveModule) {
1115 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1116 << Id[I].first << ActiveModule->getTopLevelModule();
1117 } else {
1118 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1119 }
1120 HadError = true;
1121 return;
1122 }
1123 }
1124
1125 StringRef ModuleName = Id.back().first;
1126 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001127
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001128 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001129 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001130 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001131
Douglas Gregora30cfe52011-11-11 19:10:28 +00001132 // Parse the opening brace.
1133 if (!Tok.is(MMToken::LBrace)) {
1134 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1135 << ModuleName;
1136 HadError = true;
1137 return;
1138 }
1139 SourceLocation LBraceLoc = consumeToken();
1140
1141 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001142 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001143 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1144 // Skip the module definition.
1145 skipUntil(MMToken::RBrace);
1146 if (Tok.is(MMToken::RBrace))
1147 consumeToken();
1148 else {
1149 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1150 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1151 HadError = true;
1152 }
1153 return;
1154 }
1155
Douglas Gregora30cfe52011-11-11 19:10:28 +00001156 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1157 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001158 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001159
1160 // Skip the module definition.
1161 skipUntil(MMToken::RBrace);
1162 if (Tok.is(MMToken::RBrace))
1163 consumeToken();
1164
1165 HadError = true;
1166 return;
1167 }
1168
1169 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001170 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1171 Explicit).first;
1172 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001173 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001174 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001175
1176 bool Done = false;
1177 do {
1178 switch (Tok.Kind) {
1179 case MMToken::EndOfFile:
1180 case MMToken::RBrace:
1181 Done = true;
1182 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001183
1184 case MMToken::ConfigMacros:
1185 parseConfigMacros();
1186 break;
1187
Douglas Gregor906d66a2013-03-20 21:10:35 +00001188 case MMToken::Conflict:
1189 parseConflict();
1190 break;
1191
Douglas Gregora30cfe52011-11-11 19:10:28 +00001192 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001193 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001194 case MMToken::ModuleKeyword:
1195 parseModuleDecl();
1196 break;
1197
Douglas Gregor90db2602011-12-02 01:47:07 +00001198 case MMToken::ExportKeyword:
1199 parseExportDecl();
1200 break;
1201
Douglas Gregor51f564f2011-12-31 04:05:44 +00001202 case MMToken::RequiresKeyword:
1203 parseRequiresDecl();
1204 break;
1205
Douglas Gregor77d029f2011-12-08 19:11:24 +00001206 case MMToken::UmbrellaKeyword: {
1207 SourceLocation UmbrellaLoc = consumeToken();
1208 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001209 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +00001210 else
1211 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001212 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001213 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001214
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001215 case MMToken::ExcludeKeyword: {
1216 SourceLocation ExcludeLoc = consumeToken();
1217 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001218 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001219 } else {
1220 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1221 << "exclude";
1222 }
1223 break;
1224 }
1225
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001226 case MMToken::PrivateKeyword: {
1227 SourceLocation PrivateLoc = consumeToken();
1228 if (Tok.is(MMToken::HeaderKeyword)) {
1229 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1230 } else {
1231 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1232 << "private";
1233 }
1234 break;
1235 }
1236
Douglas Gregor489ad432011-12-08 18:00:48 +00001237 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001238 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001239 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001240
1241 case MMToken::LinkKeyword:
1242 parseLinkDecl();
1243 break;
1244
Douglas Gregora30cfe52011-11-11 19:10:28 +00001245 default:
1246 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1247 consumeToken();
1248 break;
1249 }
1250 } while (!Done);
1251
1252 if (Tok.is(MMToken::RBrace))
1253 consumeToken();
1254 else {
1255 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1256 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1257 HadError = true;
1258 }
1259
Douglas Gregor8767dc22013-01-14 17:57:51 +00001260 // If the active module is a top-level framework, and there are no link
1261 // libraries, automatically link against the framework.
1262 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1263 ActiveModule->LinkLibraries.empty()) {
1264 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1265 }
1266
Douglas Gregor587986e2011-12-07 02:23:45 +00001267 // We're done parsing this module. Pop back to the previous module.
1268 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001269}
Douglas Gregord620a842011-12-06 17:16:41 +00001270
Douglas Gregor51f564f2011-12-31 04:05:44 +00001271/// \brief Parse a requires declaration.
1272///
1273/// requires-declaration:
1274/// 'requires' feature-list
1275///
1276/// feature-list:
1277/// identifier ',' feature-list
1278/// identifier
1279void ModuleMapParser::parseRequiresDecl() {
1280 assert(Tok.is(MMToken::RequiresKeyword));
1281
1282 // Parse 'requires' keyword.
1283 consumeToken();
1284
1285 // Parse the feature-list.
1286 do {
1287 if (!Tok.is(MMToken::Identifier)) {
1288 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1289 HadError = true;
1290 return;
1291 }
1292
1293 // Consume the feature name.
1294 std::string Feature = Tok.getString();
1295 consumeToken();
1296
1297 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001298 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001299
1300 if (!Tok.is(MMToken::Comma))
1301 break;
1302
1303 // Consume the comma.
1304 consumeToken();
1305 } while (true);
1306}
1307
Douglas Gregord620a842011-12-06 17:16:41 +00001308/// \brief Append to \p Paths the set of paths needed to get to the
1309/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001310static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001311 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001312 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001313 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001314 for (; Mod; Mod = Mod->Parent) {
1315 if (Mod->IsFramework)
1316 Paths.push_back(Mod->Name);
1317 }
1318
1319 if (Paths.empty())
1320 return;
1321
1322 // Add Frameworks/Name.framework for each subframework.
1323 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1324 llvm::sys::path::append(Path, "Frameworks");
1325 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1326 }
1327}
1328
Douglas Gregora30cfe52011-11-11 19:10:28 +00001329/// \brief Parse a header declaration.
1330///
1331/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001332/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001333/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001334void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1335 SourceLocation LeadingLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001336 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001337 consumeToken();
1338
Douglas Gregora30cfe52011-11-11 19:10:28 +00001339 // Parse the header name.
1340 if (!Tok.is(MMToken::StringLiteral)) {
1341 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1342 << "header";
1343 HadError = true;
1344 return;
1345 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001346 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001347 SourceLocation FileNameLoc = consumeToken();
1348
Douglas Gregor77d029f2011-12-08 19:11:24 +00001349 // Check whether we already have an umbrella.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001350 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Douglas Gregor77d029f2011-12-08 19:11:24 +00001351 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1352 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001353 HadError = true;
1354 return;
1355 }
1356
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001357 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001358 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001359 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001360 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001361 if (llvm::sys::path::is_absolute(FileName)) {
1362 PathName = FileName;
1363 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001364 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1365 PathName = Dir->getName();
1366 llvm::sys::path::append(PathName, FileName);
1367 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001368 } else {
1369 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001370 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001371 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001372
Douglas Gregord620a842011-12-06 17:16:41 +00001373 if (ActiveModule->isPartOfFramework()) {
1374 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001375
1376 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001377 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001378 llvm::sys::path::append(PathName, FileName);
1379 File = SourceMgr.getFileManager().getFile(PathName);
1380
1381 if (!File) {
1382 // Check whether this file is in the private headers.
1383 PathName.resize(PathLength);
1384 llvm::sys::path::append(PathName, "PrivateHeaders");
1385 llvm::sys::path::append(PathName, FileName);
1386 File = SourceMgr.getFileManager().getFile(PathName);
1387 }
1388 } else {
1389 // Lookup for normal headers.
1390 llvm::sys::path::append(PathName, FileName);
1391 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001392
1393 // If this is a system module with a top-level header, this header
1394 // may have a counterpart (or replacement) in the set of headers
1395 // supplied by Clang. Find that builtin header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001396 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1397 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1398 isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001399 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001400 llvm::sys::path::append(BuiltinPathName, FileName);
1401 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1402
1403 // If Clang supplies this header but the underlying system does not,
1404 // just silently swap in our builtin version. Otherwise, we'll end
1405 // up adding both (later).
1406 if (!File && BuiltinFile) {
1407 File = BuiltinFile;
1408 BuiltinFile = 0;
1409 }
1410 }
Douglas Gregord620a842011-12-06 17:16:41 +00001411 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001412 }
Douglas Gregora8654052011-11-17 22:09:43 +00001413
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001414 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1415 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001416 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001417 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001418 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001419 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001420 HadError = true;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001421 } else if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001422 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001423 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001424 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001425 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001426 HadError = true;
1427 } else {
1428 // Record this umbrella header.
1429 Map.setUmbrellaHeader(ActiveModule, File);
1430 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001431 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001432 // Record this header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001433 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1434 if (LeadingToken == MMToken::ExcludeKeyword)
1435 Role = ModuleMap::ExcludedHeader;
1436 else if (LeadingToken == MMToken::PrivateKeyword)
1437 Role = ModuleMap::PrivateHeader;
1438 else
1439 assert(LeadingToken == MMToken::HeaderKeyword);
1440
1441 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001442
1443 // If there is a builtin counterpart to this file, add it now.
1444 if (BuiltinFile)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001445 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001446 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001447 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor71f49f52012-11-15 19:47:16 +00001448 // Ignore excluded header files. They're optional anyway.
1449
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001450 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001451 << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001452 HadError = true;
1453 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001454}
1455
Douglas Gregor77d029f2011-12-08 19:11:24 +00001456/// \brief Parse an umbrella directory declaration.
1457///
1458/// umbrella-dir-declaration:
1459/// umbrella string-literal
1460void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1461 // Parse the directory name.
1462 if (!Tok.is(MMToken::StringLiteral)) {
1463 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1464 << "umbrella";
1465 HadError = true;
1466 return;
1467 }
1468
1469 std::string DirName = Tok.getString();
1470 SourceLocation DirNameLoc = consumeToken();
1471
1472 // Check whether we already have an umbrella.
1473 if (ActiveModule->Umbrella) {
1474 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1475 << ActiveModule->getFullModuleName();
1476 HadError = true;
1477 return;
1478 }
1479
1480 // Look for this file.
1481 const DirectoryEntry *Dir = 0;
1482 if (llvm::sys::path::is_absolute(DirName))
1483 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1484 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001485 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001486 PathName = Directory->getName();
1487 llvm::sys::path::append(PathName, DirName);
1488 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1489 }
1490
1491 if (!Dir) {
1492 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1493 << DirName;
1494 HadError = true;
1495 return;
1496 }
1497
1498 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1499 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1500 << OwningModule->getFullModuleName();
1501 HadError = true;
1502 return;
1503 }
1504
1505 // Record this umbrella directory.
1506 Map.setUmbrellaDir(ActiveModule, Dir);
1507}
1508
Douglas Gregor90db2602011-12-02 01:47:07 +00001509/// \brief Parse a module export declaration.
1510///
1511/// export-declaration:
1512/// 'export' wildcard-module-id
1513///
1514/// wildcard-module-id:
1515/// identifier
1516/// '*'
1517/// identifier '.' wildcard-module-id
1518void ModuleMapParser::parseExportDecl() {
1519 assert(Tok.is(MMToken::ExportKeyword));
1520 SourceLocation ExportLoc = consumeToken();
1521
1522 // Parse the module-id with an optional wildcard at the end.
1523 ModuleId ParsedModuleId;
1524 bool Wildcard = false;
1525 do {
1526 if (Tok.is(MMToken::Identifier)) {
1527 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1528 Tok.getLocation()));
1529 consumeToken();
1530
1531 if (Tok.is(MMToken::Period)) {
1532 consumeToken();
1533 continue;
1534 }
1535
1536 break;
1537 }
1538
1539 if(Tok.is(MMToken::Star)) {
1540 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001541 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001542 break;
1543 }
1544
1545 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1546 HadError = true;
1547 return;
1548 } while (true);
1549
1550 Module::UnresolvedExportDecl Unresolved = {
1551 ExportLoc, ParsedModuleId, Wildcard
1552 };
1553 ActiveModule->UnresolvedExports.push_back(Unresolved);
1554}
1555
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001556/// \brief Parse a link declaration.
1557///
1558/// module-declaration:
1559/// 'link' 'framework'[opt] string-literal
1560void ModuleMapParser::parseLinkDecl() {
1561 assert(Tok.is(MMToken::LinkKeyword));
1562 SourceLocation LinkLoc = consumeToken();
1563
1564 // Parse the optional 'framework' keyword.
1565 bool IsFramework = false;
1566 if (Tok.is(MMToken::FrameworkKeyword)) {
1567 consumeToken();
1568 IsFramework = true;
1569 }
1570
1571 // Parse the library name
1572 if (!Tok.is(MMToken::StringLiteral)) {
1573 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1574 << IsFramework << SourceRange(LinkLoc);
1575 HadError = true;
1576 return;
1577 }
1578
1579 std::string LibraryName = Tok.getString();
1580 consumeToken();
1581 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1582 IsFramework));
1583}
1584
Douglas Gregor63a72682013-03-20 00:22:05 +00001585/// \brief Parse a configuration macro declaration.
1586///
1587/// module-declaration:
1588/// 'config_macros' attributes[opt] config-macro-list?
1589///
1590/// config-macro-list:
1591/// identifier (',' identifier)?
1592void ModuleMapParser::parseConfigMacros() {
1593 assert(Tok.is(MMToken::ConfigMacros));
1594 SourceLocation ConfigMacrosLoc = consumeToken();
1595
1596 // Only top-level modules can have configuration macros.
1597 if (ActiveModule->Parent) {
1598 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1599 }
1600
1601 // Parse the optional attributes.
1602 Attributes Attrs;
1603 parseOptionalAttributes(Attrs);
1604 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1605 ActiveModule->ConfigMacrosExhaustive = true;
1606 }
1607
1608 // If we don't have an identifier, we're done.
1609 if (!Tok.is(MMToken::Identifier))
1610 return;
1611
1612 // Consume the first identifier.
1613 if (!ActiveModule->Parent) {
1614 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1615 }
1616 consumeToken();
1617
1618 do {
1619 // If there's a comma, consume it.
1620 if (!Tok.is(MMToken::Comma))
1621 break;
1622 consumeToken();
1623
1624 // We expect to see a macro name here.
1625 if (!Tok.is(MMToken::Identifier)) {
1626 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1627 break;
1628 }
1629
1630 // Consume the macro name.
1631 if (!ActiveModule->Parent) {
1632 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1633 }
1634 consumeToken();
1635 } while (true);
1636}
1637
Douglas Gregor906d66a2013-03-20 21:10:35 +00001638/// \brief Format a module-id into a string.
1639static std::string formatModuleId(const ModuleId &Id) {
1640 std::string result;
1641 {
1642 llvm::raw_string_ostream OS(result);
1643
1644 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1645 if (I)
1646 OS << ".";
1647 OS << Id[I].first;
1648 }
1649 }
1650
1651 return result;
1652}
1653
1654/// \brief Parse a conflict declaration.
1655///
1656/// module-declaration:
1657/// 'conflict' module-id ',' string-literal
1658void ModuleMapParser::parseConflict() {
1659 assert(Tok.is(MMToken::Conflict));
1660 SourceLocation ConflictLoc = consumeToken();
1661 Module::UnresolvedConflict Conflict;
1662
1663 // Parse the module-id.
1664 if (parseModuleId(Conflict.Id))
1665 return;
1666
1667 // Parse the ','.
1668 if (!Tok.is(MMToken::Comma)) {
1669 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1670 << SourceRange(ConflictLoc);
1671 return;
1672 }
1673 consumeToken();
1674
1675 // Parse the message.
1676 if (!Tok.is(MMToken::StringLiteral)) {
1677 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1678 << formatModuleId(Conflict.Id);
1679 return;
1680 }
1681 Conflict.Message = Tok.getString().str();
1682 consumeToken();
1683
1684 // Add this unresolved conflict.
1685 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1686}
1687
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001688/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001689///
1690/// module-declaration:
1691/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1692/// { inferred-module-member* }
1693///
1694/// inferred-module-member:
1695/// 'export' '*'
1696/// 'exclude' identifier
1697void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001698 assert(Tok.is(MMToken::Star));
1699 SourceLocation StarLoc = consumeToken();
1700 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001701
Douglas Gregor1e123682011-12-05 22:27:44 +00001702 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001703 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001704 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1705 Failed = true;
1706 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001707
1708 if (ActiveModule) {
1709 // Inferred modules must have umbrella directories.
1710 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1711 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1712 Failed = true;
1713 }
1714
1715 // Check for redefinition of an inferred module.
1716 if (!Failed && ActiveModule->InferSubmodules) {
1717 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1718 if (ActiveModule->InferredSubmoduleLoc.isValid())
1719 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1720 diag::note_mmap_prev_definition);
1721 Failed = true;
1722 }
1723
1724 // Check for the 'framework' keyword, which is not permitted here.
1725 if (Framework) {
1726 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1727 Framework = false;
1728 }
1729 } else if (Explicit) {
1730 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1731 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001732 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001733
Douglas Gregor1e123682011-12-05 22:27:44 +00001734 // If there were any problems with this inferred submodule, skip its body.
1735 if (Failed) {
1736 if (Tok.is(MMToken::LBrace)) {
1737 consumeToken();
1738 skipUntil(MMToken::RBrace);
1739 if (Tok.is(MMToken::RBrace))
1740 consumeToken();
1741 }
1742 HadError = true;
1743 return;
1744 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001745
1746 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001747 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001748 parseOptionalAttributes(Attrs);
1749
1750 if (ActiveModule) {
1751 // Note that we have an inferred submodule.
1752 ActiveModule->InferSubmodules = true;
1753 ActiveModule->InferredSubmoduleLoc = StarLoc;
1754 ActiveModule->InferExplicitSubmodules = Explicit;
1755 } else {
1756 // We'll be inferring framework modules for this directory.
1757 Map.InferredDirectories[Directory].InferModules = true;
1758 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1759 }
1760
Douglas Gregor1e123682011-12-05 22:27:44 +00001761 // Parse the opening brace.
1762 if (!Tok.is(MMToken::LBrace)) {
1763 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1764 HadError = true;
1765 return;
1766 }
1767 SourceLocation LBraceLoc = consumeToken();
1768
1769 // Parse the body of the inferred submodule.
1770 bool Done = false;
1771 do {
1772 switch (Tok.Kind) {
1773 case MMToken::EndOfFile:
1774 case MMToken::RBrace:
1775 Done = true;
1776 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001777
1778 case MMToken::ExcludeKeyword: {
1779 if (ActiveModule) {
1780 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001781 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001782 consumeToken();
1783 break;
1784 }
1785
1786 consumeToken();
1787 if (!Tok.is(MMToken::Identifier)) {
1788 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1789 break;
1790 }
1791
1792 Map.InferredDirectories[Directory].ExcludedModules
1793 .push_back(Tok.getString());
1794 consumeToken();
1795 break;
1796 }
1797
1798 case MMToken::ExportKeyword:
1799 if (!ActiveModule) {
1800 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001801 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001802 consumeToken();
1803 break;
1804 }
1805
Douglas Gregor1e123682011-12-05 22:27:44 +00001806 consumeToken();
1807 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001808 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001809 else
1810 Diags.Report(Tok.getLocation(),
1811 diag::err_mmap_expected_export_wildcard);
1812 consumeToken();
1813 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001814
Douglas Gregor1e123682011-12-05 22:27:44 +00001815 case MMToken::ExplicitKeyword:
1816 case MMToken::ModuleKeyword:
1817 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001818 case MMToken::PrivateKeyword:
Douglas Gregor1e123682011-12-05 22:27:44 +00001819 case MMToken::UmbrellaKeyword:
1820 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001821 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001822 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001823 consumeToken();
1824 break;
1825 }
1826 } while (!Done);
1827
1828 if (Tok.is(MMToken::RBrace))
1829 consumeToken();
1830 else {
1831 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1832 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1833 HadError = true;
1834 }
1835}
1836
Douglas Gregor82e52372012-11-06 19:39:40 +00001837/// \brief Parse optional attributes.
1838///
1839/// attributes:
1840/// attribute attributes
1841/// attribute
1842///
1843/// attribute:
1844/// [ identifier ]
1845///
1846/// \param Attrs Will be filled in with the parsed attributes.
1847///
1848/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001849bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001850 bool HadError = false;
1851
1852 while (Tok.is(MMToken::LSquare)) {
1853 // Consume the '['.
1854 SourceLocation LSquareLoc = consumeToken();
1855
1856 // Check whether we have an attribute name here.
1857 if (!Tok.is(MMToken::Identifier)) {
1858 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1859 skipUntil(MMToken::RSquare);
1860 if (Tok.is(MMToken::RSquare))
1861 consumeToken();
1862 HadError = true;
1863 }
1864
1865 // Decode the attribute name.
1866 AttributeKind Attribute
1867 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001868 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00001869 .Case("system", AT_system)
1870 .Default(AT_unknown);
1871 switch (Attribute) {
1872 case AT_unknown:
1873 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1874 << Tok.getString();
1875 break;
1876
1877 case AT_system:
1878 Attrs.IsSystem = true;
1879 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001880
1881 case AT_exhaustive:
1882 Attrs.IsExhaustive = true;
1883 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001884 }
1885 consumeToken();
1886
1887 // Consume the ']'.
1888 if (!Tok.is(MMToken::RSquare)) {
1889 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1890 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1891 skipUntil(MMToken::RSquare);
1892 HadError = true;
1893 }
1894
1895 if (Tok.is(MMToken::RSquare))
1896 consumeToken();
1897 }
1898
1899 return HadError;
1900}
1901
Douglas Gregor6a1db482011-12-09 02:04:43 +00001902/// \brief If there is a specific header search directory due the presence
1903/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1904const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1905 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1906 // If we have an umbrella directory, use that.
1907 if (Mod->hasUmbrellaDir())
1908 return Mod->getUmbrellaDir();
1909
1910 // If we have a framework directory, stop looking.
1911 if (Mod->IsFramework)
1912 return 0;
1913 }
1914
1915 return 0;
1916}
1917
Douglas Gregora30cfe52011-11-11 19:10:28 +00001918/// \brief Parse a module map file.
1919///
1920/// module-map-file:
1921/// module-declaration*
1922bool ModuleMapParser::parseModuleMapFile() {
1923 do {
1924 switch (Tok.Kind) {
1925 case MMToken::EndOfFile:
1926 return HadError;
1927
Douglas Gregor587986e2011-12-07 02:23:45 +00001928 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001929 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001930 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001931 parseModuleDecl();
1932 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001933
Douglas Gregor51f564f2011-12-31 04:05:44 +00001934 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00001935 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00001936 case MMToken::Conflict:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001937 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001938 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001939 case MMToken::HeaderKeyword:
1940 case MMToken::Identifier:
1941 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001942 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001943 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001944 case MMToken::Period:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001945 case MMToken::PrivateKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001946 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001947 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001948 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001949 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001950 case MMToken::StringLiteral:
1951 case MMToken::UmbrellaKeyword:
1952 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1953 HadError = true;
1954 consumeToken();
1955 break;
1956 }
1957 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001958}
1959
1960bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001961 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1962 = ParsedModuleMap.find(File);
1963 if (Known != ParsedModuleMap.end())
1964 return Known->second;
1965
Douglas Gregordc58aa72012-01-30 06:01:29 +00001966 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001967 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1968 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1969 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001970 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001971
1972 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001973 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1974 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001975 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001976 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001977 bool Result = Parser.parseModuleMapFile();
1978 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001979 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001980 return Result;
1981}