blob: 1458a73a7d32fde1d9c4f70920d6bf2db2633f92 [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"
Douglas Gregor8b6d3de2011-11-11 21:55:48 +000030#include "llvm/Support/PathV2.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 Gregor51f564f2011-12-31 04:05:44 +000086ModuleMap::ModuleMap(FileManager &FileMgr, const 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),
90 BuiltinIncludeDir(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 Gregora30cfe52011-11-11 19:10:28 +000095 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
96 SourceMgr = new SourceManager(*Diags, FileMgr);
97}
98
99ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +0000100 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
101 IEnd = Modules.end();
102 I != IEnd; ++I) {
103 delete I->getValue();
104 }
105
Douglas Gregora30cfe52011-11-11 19:10:28 +0000106 delete SourceMgr;
107}
108
Douglas Gregordc58aa72012-01-30 06:01:29 +0000109void ModuleMap::setTarget(const TargetInfo &Target) {
110 assert((!this->Target || this->Target == &Target) &&
111 "Improper target override");
112 this->Target = &Target;
113}
114
Douglas Gregor8b48e082012-10-12 21:15:50 +0000115/// \brief "Sanitize" a filename so that it can be used as an identifier.
116static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
117 SmallVectorImpl<char> &Buffer) {
118 if (Name.empty())
119 return Name;
120
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000121 if (!isValidIdentifier(Name)) {
Douglas Gregor8b48e082012-10-12 21:15:50 +0000122 // If we don't already have something with the form of an identifier,
123 // create a buffer with the sanitized name.
124 Buffer.clear();
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000125 if (isDigit(Name[0]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000126 Buffer.push_back('_');
127 Buffer.reserve(Buffer.size() + Name.size());
128 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000129 if (isIdentifierBody(Name[I]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000130 Buffer.push_back(Name[I]);
131 else
132 Buffer.push_back('_');
133 }
134
135 Name = StringRef(Buffer.data(), Buffer.size());
136 }
137
138 while (llvm::StringSwitch<bool>(Name)
139#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
140#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
141#include "clang/Basic/TokenKinds.def"
142 .Default(false)) {
143 if (Name.data() != Buffer.data())
144 Buffer.append(Name.begin(), Name.end());
145 Buffer.push_back('_');
146 Name = StringRef(Buffer.data(), Buffer.size());
147 }
148
149 return Name;
150}
151
Douglas Gregordb3910b2013-05-02 17:58:30 +0000152/// \brief Determine whether the given file name is the name of a builtin
153/// header, supplied by Clang to replace, override, or augment existing system
154/// headers.
155static bool isBuiltinHeader(StringRef FileName) {
156 return llvm::StringSwitch<bool>(FileName)
157 .Case("float.h", true)
158 .Case("iso646.h", true)
159 .Case("limits.h", true)
160 .Case("stdalign.h", true)
161 .Case("stdarg.h", true)
162 .Case("stdbool.h", true)
163 .Case("stddef.h", true)
164 .Case("stdint.h", true)
165 .Case("tgmath.h", true)
166 .Case("unwind.h", true)
167 .Default(false);
168}
169
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000170Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000171 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000172 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000173 // If a header is not available, don't report that it maps to anything.
174 if (!Known->second.isAvailable())
Douglas Gregor51f564f2011-12-31 04:05:44 +0000175 return 0;
176
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000177 return Known->second.getModule();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000178 }
Douglas Gregordb3910b2013-05-02 17:58:30 +0000179
180 // If we've found a builtin header within Clang's builtin include directory,
181 // load all of the module maps to see if it will get associated with a
182 // specific module (e.g., in /usr/include).
183 if (File->getDir() == BuiltinIncludeDir &&
184 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
185 SmallVector<Module *, 4> AllModules;
186 HeaderInfo.collectAllModules(AllModules);
187
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())
193 return 0;
194
195 return Known->second.getModule();
196 }
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
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000265 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
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())
270 return 0;
271
Douglas Gregore209e502011-12-06 01:10:29 +0000272 return Result;
273 }
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
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000286 return 0;
287}
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);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000390 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000391 Modules[Name] = Result;
392 return std::make_pair(Result, true);
393}
394
Douglas Gregor82e52372012-11-06 19:39:40 +0000395bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000396 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000397 // Check whether we have already looked into the parent directory
398 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000399 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000400 inferred = InferredDirectories.find(ParentDir);
401 if (inferred == InferredDirectories.end())
402 return false;
403
404 if (!inferred->second.InferModules)
405 return false;
406
407 // We're allowed to infer for this directory, but make sure it's okay
408 // to infer this particular module.
409 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
410 inferred->second.ExcludedModules.end(),
411 Name) == inferred->second.ExcludedModules.end();
412
413 if (canInfer && inferred->second.InferSystemModules)
414 IsSystem = true;
415
416 return canInfer;
417}
418
Douglas Gregor8767dc22013-01-14 17:57:51 +0000419/// \brief For a framework module, infer the framework against which we
420/// should link.
421static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
422 FileManager &FileMgr) {
423 assert(Mod->IsFramework && "Can only infer linking for framework modules");
424 assert(!Mod->isSubFramework() &&
425 "Can only infer linking for top-level frameworks");
426
427 SmallString<128> LibName;
428 LibName += FrameworkDir->getName();
429 llvm::sys::path::append(LibName, Mod->Name);
430 if (FileMgr.getFile(LibName)) {
431 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
432 /*IsFramework=*/true));
433 }
434}
435
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000436Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000437ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000438 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000439 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000440 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000441 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000442 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
443 return Mod;
444
445 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000446
447 // If the framework has a parent path from which we're allowed to infer
448 // a framework module, do so.
449 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000450 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000451
Douglas Gregor7005b902013-01-10 01:43:00 +0000452 // Note: as an egregious but useful hack we use the real path here, because
453 // we might be looking at an embedded framework that symlinks out to a
454 // top-level framework, and we need to infer as if we were naming the
455 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000456 StringRef FrameworkDirName
457 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000458
Douglas Gregor82e52372012-11-06 19:39:40 +0000459 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000460 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000461 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000462 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000463 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
464 // Check whether we have already looked into the parent directory
465 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000466 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000467 inferred = InferredDirectories.find(ParentDir);
468 if (inferred == InferredDirectories.end()) {
469 // We haven't looked here before. Load a module map, if there is
470 // one.
471 SmallString<128> ModMapPath = Parent;
472 llvm::sys::path::append(ModMapPath, "module.map");
473 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
474 parseModuleMapFile(ModMapFile);
475 inferred = InferredDirectories.find(ParentDir);
476 }
477
478 if (inferred == InferredDirectories.end())
479 inferred = InferredDirectories.insert(
480 std::make_pair(ParentDir, InferredDirectory())).first;
481 }
482
483 if (inferred->second.InferModules) {
484 // We're allowed to infer for this directory, but make sure it's okay
485 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000486 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000487 canInfer = std::find(inferred->second.ExcludedModules.begin(),
488 inferred->second.ExcludedModules.end(),
489 Name) == inferred->second.ExcludedModules.end();
490
491 if (inferred->second.InferSystemModules)
492 IsSystem = true;
493 }
494 }
495 }
496
497 // If we're not allowed to infer a framework module, don't.
498 if (!canInfer)
499 return 0;
500 }
501
502
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000503 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000504 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000505 llvm::sys::path::append(UmbrellaName, "Headers");
506 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000507 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000508
509 // FIXME: If there's no umbrella header, we could probably scan the
510 // framework to load *everything*. But, it's not clear that this is a good
511 // idea.
512 if (!UmbrellaHeader)
513 return 0;
514
Douglas Gregorac252a32011-12-06 19:39:29 +0000515 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
516 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000517 if (IsSystem)
518 Result->IsSystem = IsSystem;
519
Douglas Gregorb7a78192012-01-04 23:32:19 +0000520 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000521 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000522
Douglas Gregor489ad432011-12-08 18:00:48 +0000523 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000524 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000525 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000526 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000527
528 // export *
529 Result->Exports.push_back(Module::ExportDecl(0, true));
530
Douglas Gregore209e502011-12-06 01:10:29 +0000531 // module * { export * }
532 Result->InferSubmodules = true;
533 Result->InferExportWildcard = true;
534
Douglas Gregorac252a32011-12-06 19:39:29 +0000535 // Look for subframeworks.
536 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000537 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000538 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000539 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000540 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000541 llvm::sys::path::native(SubframeworksDirName.str(),
542 SubframeworksDirNameNative);
543 for (llvm::sys::fs::directory_iterator
544 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000545 Dir != DirEnd && !EC; Dir.increment(EC)) {
546 if (!StringRef(Dir->path()).endswith(".framework"))
547 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000548
Douglas Gregorac252a32011-12-06 19:39:29 +0000549 if (const DirectoryEntry *SubframeworkDir
550 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000551 // Note: as an egregious but useful hack, we use the real path here and
552 // check whether it is actually a subdirectory of the parent directory.
553 // This will not be the case if the 'subframework' is actually a symlink
554 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000555 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
556 bool FoundParent = false;
557 do {
558 // Get the parent directory name.
559 SubframeworkDirName
560 = llvm::sys::path::parent_path(SubframeworkDirName);
561 if (SubframeworkDirName.empty())
562 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000563
Douglas Gregor713b7c02013-01-26 00:55:12 +0000564 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
565 FoundParent = true;
566 break;
567 }
568 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000569
Douglas Gregor713b7c02013-01-26 00:55:12 +0000570 if (!FoundParent)
571 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000572
Douglas Gregorac252a32011-12-06 19:39:29 +0000573 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000574 SmallString<32> NameBuf;
575 inferFrameworkModule(sanitizeFilenameAsIdentifier(
576 llvm::sys::path::stem(Dir->path()), NameBuf),
577 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000578 }
579 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000580
Douglas Gregor8767dc22013-01-14 17:57:51 +0000581 // If the module is a top-level framework, automatically link against the
582 // framework.
583 if (!Result->isSubFramework()) {
584 inferFrameworkLink(Result, FrameworkDir, FileMgr);
585 }
586
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000587 return Result;
588}
589
Douglas Gregore209e502011-12-06 01:10:29 +0000590void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000591 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000592 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000593 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000594}
595
Douglas Gregor77d029f2011-12-08 19:11:24 +0000596void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
597 Mod->Umbrella = UmbrellaDir;
598 UmbrellaDirs[UmbrellaDir] = Mod;
599}
600
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000601void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
602 bool Excluded) {
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000603 if (Excluded) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000604 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000605 } else {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000606 Mod->Headers.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000607 HeaderInfo.MarkFileModuleHeader(Header);
608 }
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000609 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000610}
611
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000612const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000613ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000614 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
615 return 0;
616
617 return SourceMgr->getFileEntryForID(
618 SourceMgr->getFileID(Module->DefinitionLoc));
619}
620
Douglas Gregora30cfe52011-11-11 19:10:28 +0000621void ModuleMap::dump() {
622 llvm::errs() << "Modules:";
623 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
624 MEnd = Modules.end();
625 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000626 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000627
628 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000629 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000630 H != HEnd; ++H) {
631 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000632 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000633 }
634}
635
Douglas Gregor90db2602011-12-02 01:47:07 +0000636bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
637 bool HadError = false;
638 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
639 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
640 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000641 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000642 Mod->Exports.push_back(Export);
643 else
644 HadError = true;
645 }
646 Mod->UnresolvedExports.clear();
647 return HadError;
648}
649
Douglas Gregor906d66a2013-03-20 21:10:35 +0000650bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
651 bool HadError = false;
652 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
653 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
654 Mod, Complain);
655 if (!OtherMod) {
656 HadError = true;
657 continue;
658 }
659
660 Module::Conflict Conflict;
661 Conflict.Other = OtherMod;
662 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
663 Mod->Conflicts.push_back(Conflict);
664 }
665 Mod->UnresolvedConflicts.clear();
666 return HadError;
667}
668
Douglas Gregor55988682011-12-05 16:33:54 +0000669Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
670 if (Loc.isInvalid())
671 return 0;
672
673 // Use the expansion location to determine which module we're in.
674 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
675 if (!ExpansionLoc.isFileID())
676 return 0;
677
678
679 const SourceManager &SrcMgr = Loc.getManager();
680 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000681
Douglas Gregor303aae92012-01-06 17:19:32 +0000682 while (const FileEntry *ExpansionFile
683 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
684 // Find the module that owns this header (if any).
685 if (Module *Mod = findModuleForHeader(ExpansionFile))
686 return Mod;
687
688 // No module owns this header, so look up the inclusion chain to see if
689 // any included header has an associated module.
690 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
691 if (IncludeLoc.isInvalid())
692 return 0;
693
694 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
695 }
696
697 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000698}
699
Douglas Gregora30cfe52011-11-11 19:10:28 +0000700//----------------------------------------------------------------------------//
701// Module map file parser
702//----------------------------------------------------------------------------//
703
704namespace clang {
705 /// \brief A token in a module map file.
706 struct MMToken {
707 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000708 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000709 ConfigMacros,
Douglas Gregor906d66a2013-03-20 21:10:35 +0000710 Conflict,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000711 EndOfFile,
712 HeaderKeyword,
713 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000714 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000715 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000716 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000717 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000718 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000719 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000720 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000721 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000722 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000723 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000724 StringLiteral,
725 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000726 RBrace,
727 LSquare,
728 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000729 } Kind;
730
731 unsigned Location;
732 unsigned StringLength;
733 const char *StringData;
734
735 void clear() {
736 Kind = EndOfFile;
737 Location = 0;
738 StringLength = 0;
739 StringData = 0;
740 }
741
742 bool is(TokenKind K) const { return Kind == K; }
743
744 SourceLocation getLocation() const {
745 return SourceLocation::getFromRawEncoding(Location);
746 }
747
748 StringRef getString() const {
749 return StringRef(StringData, StringLength);
750 }
751 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000752
753 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000754 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000755 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000756
757 /// \brief Whether this is a system module.
758 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000759
760 /// \brief Whether this is an exhaustive set of configuration macros.
761 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000762 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000763
Douglas Gregor82e52372012-11-06 19:39:40 +0000764
Douglas Gregora30cfe52011-11-11 19:10:28 +0000765 class ModuleMapParser {
766 Lexer &L;
767 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000768
769 /// \brief Default target information, used only for string literal
770 /// parsing.
771 const TargetInfo *Target;
772
Douglas Gregora30cfe52011-11-11 19:10:28 +0000773 DiagnosticsEngine &Diags;
774 ModuleMap &Map;
775
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000776 /// \brief The directory that this module map resides in.
777 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000778
779 /// \brief The directory containing Clang-supplied headers.
780 const DirectoryEntry *BuiltinIncludeDir;
781
Douglas Gregora30cfe52011-11-11 19:10:28 +0000782 /// \brief Whether an error occurred.
783 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000784
Douglas Gregora30cfe52011-11-11 19:10:28 +0000785 /// \brief Stores string data for the various string literals referenced
786 /// during parsing.
787 llvm::BumpPtrAllocator StringData;
788
789 /// \brief The current token.
790 MMToken Tok;
791
792 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000793 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000794
795 /// \brief Consume the current token and return its location.
796 SourceLocation consumeToken();
797
798 /// \brief Skip tokens until we reach the a token with the given kind
799 /// (or the end of the file).
800 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000801
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000802 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000803 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000804 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000805 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000806 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000807 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000808 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000809 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000810 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000811 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000812 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000813 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000814
Douglas Gregor6a1db482011-12-09 02:04:43 +0000815 const DirectoryEntry *getOverriddenHeaderSearchDir();
816
Douglas Gregora30cfe52011-11-11 19:10:28 +0000817 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000818 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000819 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000820 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000821 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000822 const DirectoryEntry *Directory,
823 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000824 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000825 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
826 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000827 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000828 Tok.clear();
829 consumeToken();
830 }
831
832 bool parseModuleMapFile();
833 };
834}
835
836SourceLocation ModuleMapParser::consumeToken() {
837retry:
838 SourceLocation Result = Tok.getLocation();
839 Tok.clear();
840
841 Token LToken;
842 L.LexFromRawLexer(LToken);
843 Tok.Location = LToken.getLocation().getRawEncoding();
844 switch (LToken.getKind()) {
845 case tok::raw_identifier:
846 Tok.StringData = LToken.getRawIdentifierData();
847 Tok.StringLength = LToken.getLength();
848 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000849 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000850 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000851 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000852 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000853 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000854 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000855 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000856 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000857 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000858 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000859 .Case("umbrella", MMToken::UmbrellaKeyword)
860 .Default(MMToken::Identifier);
861 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000862
863 case tok::comma:
864 Tok.Kind = MMToken::Comma;
865 break;
866
Douglas Gregora30cfe52011-11-11 19:10:28 +0000867 case tok::eof:
868 Tok.Kind = MMToken::EndOfFile;
869 break;
870
871 case tok::l_brace:
872 Tok.Kind = MMToken::LBrace;
873 break;
874
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000875 case tok::l_square:
876 Tok.Kind = MMToken::LSquare;
877 break;
878
Douglas Gregor90db2602011-12-02 01:47:07 +0000879 case tok::period:
880 Tok.Kind = MMToken::Period;
881 break;
882
Douglas Gregora30cfe52011-11-11 19:10:28 +0000883 case tok::r_brace:
884 Tok.Kind = MMToken::RBrace;
885 break;
886
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000887 case tok::r_square:
888 Tok.Kind = MMToken::RSquare;
889 break;
890
Douglas Gregor90db2602011-12-02 01:47:07 +0000891 case tok::star:
892 Tok.Kind = MMToken::Star;
893 break;
894
Douglas Gregora30cfe52011-11-11 19:10:28 +0000895 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000896 if (LToken.hasUDSuffix()) {
897 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
898 HadError = true;
899 goto retry;
900 }
901
Douglas Gregora30cfe52011-11-11 19:10:28 +0000902 // Parse the string literal.
903 LangOptions LangOpts;
904 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
905 if (StringLiteral.hadError)
906 goto retry;
907
908 // Copy the string literal into our string data allocator.
909 unsigned Length = StringLiteral.GetStringLength();
910 char *Saved = StringData.Allocate<char>(Length + 1);
911 memcpy(Saved, StringLiteral.GetString().data(), Length);
912 Saved[Length] = 0;
913
914 // Form the token.
915 Tok.Kind = MMToken::StringLiteral;
916 Tok.StringData = Saved;
917 Tok.StringLength = Length;
918 break;
919 }
920
921 case tok::comment:
922 goto retry;
923
924 default:
925 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
926 HadError = true;
927 goto retry;
928 }
929
930 return Result;
931}
932
933void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
934 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000935 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000936 do {
937 switch (Tok.Kind) {
938 case MMToken::EndOfFile:
939 return;
940
941 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000942 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000943 return;
944
945 ++braceDepth;
946 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000947
948 case MMToken::LSquare:
949 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
950 return;
951
952 ++squareDepth;
953 break;
954
Douglas Gregora30cfe52011-11-11 19:10:28 +0000955 case MMToken::RBrace:
956 if (braceDepth > 0)
957 --braceDepth;
958 else if (Tok.is(K))
959 return;
960 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000961
962 case MMToken::RSquare:
963 if (squareDepth > 0)
964 --squareDepth;
965 else if (Tok.is(K))
966 return;
967 break;
968
Douglas Gregora30cfe52011-11-11 19:10:28 +0000969 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000970 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000971 return;
972 break;
973 }
974
975 consumeToken();
976 } while (true);
977}
978
Douglas Gregor587986e2011-12-07 02:23:45 +0000979/// \brief Parse a module-id.
980///
981/// module-id:
982/// identifier
983/// identifier '.' module-id
984///
985/// \returns true if an error occurred, false otherwise.
986bool ModuleMapParser::parseModuleId(ModuleId &Id) {
987 Id.clear();
988 do {
989 if (Tok.is(MMToken::Identifier)) {
990 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
991 consumeToken();
992 } else {
993 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
994 return true;
995 }
996
997 if (!Tok.is(MMToken::Period))
998 break;
999
1000 consumeToken();
1001 } while (true);
1002
1003 return false;
1004}
1005
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001006namespace {
1007 /// \brief Enumerates the known attributes.
1008 enum AttributeKind {
1009 /// \brief An unknown attribute.
1010 AT_unknown,
1011 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001012 AT_system,
1013 /// \brief The 'exhaustive' attribute.
1014 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001015 };
1016}
1017
Douglas Gregora30cfe52011-11-11 19:10:28 +00001018/// \brief Parse a module declaration.
1019///
1020/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001021/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1022/// { module-member* }
1023///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001024/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001025/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001026/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001027/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001028/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001029/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001030///
1031/// submodule-declaration:
1032/// module-declaration
1033/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001034void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001035 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1036 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +00001037 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001038 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001039 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001040 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001041
Douglas Gregord620a842011-12-06 17:16:41 +00001042 // Parse 'explicit' keyword, if present.
1043 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001044 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001045 Explicit = true;
1046 }
1047
1048 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001049 if (Tok.is(MMToken::FrameworkKeyword)) {
1050 consumeToken();
1051 Framework = true;
1052 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001053
1054 // Parse 'module' keyword.
1055 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001056 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001057 consumeToken();
1058 HadError = true;
1059 return;
1060 }
1061 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001062
1063 // If we have a wildcard for the module name, this is an inferred submodule.
1064 // Parse it.
1065 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001066 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001067
1068 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001069 ModuleId Id;
1070 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001071 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001072 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001073 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001074
Douglas Gregor587986e2011-12-07 02:23:45 +00001075 if (ActiveModule) {
1076 if (Id.size() > 1) {
1077 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1078 << SourceRange(Id.front().second, Id.back().second);
1079
1080 HadError = true;
1081 return;
1082 }
1083 } else if (Id.size() == 1 && Explicit) {
1084 // Top-level modules can't be explicit.
1085 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1086 Explicit = false;
1087 ExplicitLoc = SourceLocation();
1088 HadError = true;
1089 }
1090
1091 Module *PreviousActiveModule = ActiveModule;
1092 if (Id.size() > 1) {
1093 // This module map defines a submodule. Go find the module of which it
1094 // is a submodule.
1095 ActiveModule = 0;
1096 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1097 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1098 ActiveModule = Next;
1099 continue;
1100 }
1101
1102 if (ActiveModule) {
1103 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1104 << Id[I].first << ActiveModule->getTopLevelModule();
1105 } else {
1106 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1107 }
1108 HadError = true;
1109 return;
1110 }
1111 }
1112
1113 StringRef ModuleName = Id.back().first;
1114 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001115
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001116 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001117 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001118 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001119
Douglas Gregora30cfe52011-11-11 19:10:28 +00001120 // Parse the opening brace.
1121 if (!Tok.is(MMToken::LBrace)) {
1122 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1123 << ModuleName;
1124 HadError = true;
1125 return;
1126 }
1127 SourceLocation LBraceLoc = consumeToken();
1128
1129 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001130 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001131 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1132 // Skip the module definition.
1133 skipUntil(MMToken::RBrace);
1134 if (Tok.is(MMToken::RBrace))
1135 consumeToken();
1136 else {
1137 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1138 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1139 HadError = true;
1140 }
1141 return;
1142 }
1143
Douglas Gregora30cfe52011-11-11 19:10:28 +00001144 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1145 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001146 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001147
1148 // Skip the module definition.
1149 skipUntil(MMToken::RBrace);
1150 if (Tok.is(MMToken::RBrace))
1151 consumeToken();
1152
1153 HadError = true;
1154 return;
1155 }
1156
1157 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001158 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1159 Explicit).first;
1160 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001161 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001162 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001163
1164 bool Done = false;
1165 do {
1166 switch (Tok.Kind) {
1167 case MMToken::EndOfFile:
1168 case MMToken::RBrace:
1169 Done = true;
1170 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001171
1172 case MMToken::ConfigMacros:
1173 parseConfigMacros();
1174 break;
1175
Douglas Gregor906d66a2013-03-20 21:10:35 +00001176 case MMToken::Conflict:
1177 parseConflict();
1178 break;
1179
Douglas Gregora30cfe52011-11-11 19:10:28 +00001180 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001181 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001182 case MMToken::ModuleKeyword:
1183 parseModuleDecl();
1184 break;
1185
Douglas Gregor90db2602011-12-02 01:47:07 +00001186 case MMToken::ExportKeyword:
1187 parseExportDecl();
1188 break;
1189
Douglas Gregor51f564f2011-12-31 04:05:44 +00001190 case MMToken::RequiresKeyword:
1191 parseRequiresDecl();
1192 break;
1193
Douglas Gregor77d029f2011-12-08 19:11:24 +00001194 case MMToken::UmbrellaKeyword: {
1195 SourceLocation UmbrellaLoc = consumeToken();
1196 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001197 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001198 else
1199 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001200 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001201 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001202
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001203 case MMToken::ExcludeKeyword: {
1204 SourceLocation ExcludeLoc = consumeToken();
1205 if (Tok.is(MMToken::HeaderKeyword)) {
1206 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1207 } else {
1208 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1209 << "exclude";
1210 }
1211 break;
1212 }
1213
Douglas Gregor489ad432011-12-08 18:00:48 +00001214 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001215 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001216 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001217
1218 case MMToken::LinkKeyword:
1219 parseLinkDecl();
1220 break;
1221
Douglas Gregora30cfe52011-11-11 19:10:28 +00001222 default:
1223 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1224 consumeToken();
1225 break;
1226 }
1227 } while (!Done);
1228
1229 if (Tok.is(MMToken::RBrace))
1230 consumeToken();
1231 else {
1232 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1233 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1234 HadError = true;
1235 }
1236
Douglas Gregor8767dc22013-01-14 17:57:51 +00001237 // If the active module is a top-level framework, and there are no link
1238 // libraries, automatically link against the framework.
1239 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1240 ActiveModule->LinkLibraries.empty()) {
1241 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1242 }
1243
Douglas Gregor587986e2011-12-07 02:23:45 +00001244 // We're done parsing this module. Pop back to the previous module.
1245 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001246}
Douglas Gregord620a842011-12-06 17:16:41 +00001247
Douglas Gregor51f564f2011-12-31 04:05:44 +00001248/// \brief Parse a requires declaration.
1249///
1250/// requires-declaration:
1251/// 'requires' feature-list
1252///
1253/// feature-list:
1254/// identifier ',' feature-list
1255/// identifier
1256void ModuleMapParser::parseRequiresDecl() {
1257 assert(Tok.is(MMToken::RequiresKeyword));
1258
1259 // Parse 'requires' keyword.
1260 consumeToken();
1261
1262 // Parse the feature-list.
1263 do {
1264 if (!Tok.is(MMToken::Identifier)) {
1265 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1266 HadError = true;
1267 return;
1268 }
1269
1270 // Consume the feature name.
1271 std::string Feature = Tok.getString();
1272 consumeToken();
1273
1274 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001275 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001276
1277 if (!Tok.is(MMToken::Comma))
1278 break;
1279
1280 // Consume the comma.
1281 consumeToken();
1282 } while (true);
1283}
1284
Douglas Gregord620a842011-12-06 17:16:41 +00001285/// \brief Append to \p Paths the set of paths needed to get to the
1286/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001287static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001288 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001289 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001290 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001291 for (; Mod; Mod = Mod->Parent) {
1292 if (Mod->IsFramework)
1293 Paths.push_back(Mod->Name);
1294 }
1295
1296 if (Paths.empty())
1297 return;
1298
1299 // Add Frameworks/Name.framework for each subframework.
1300 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1301 llvm::sys::path::append(Path, "Frameworks");
1302 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1303 }
1304}
1305
Douglas Gregora30cfe52011-11-11 19:10:28 +00001306/// \brief Parse a header declaration.
1307///
1308/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001309/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001310/// 'exclude'[opt] 'header' string-literal
1311void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1312 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001313 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001314 consumeToken();
1315
Douglas Gregor489ad432011-12-08 18:00:48 +00001316 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001317 bool Exclude = ExcludeLoc.isValid();
1318 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001319 // Parse the header name.
1320 if (!Tok.is(MMToken::StringLiteral)) {
1321 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1322 << "header";
1323 HadError = true;
1324 return;
1325 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001326 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001327 SourceLocation FileNameLoc = consumeToken();
1328
Douglas Gregor77d029f2011-12-08 19:11:24 +00001329 // Check whether we already have an umbrella.
1330 if (Umbrella && ActiveModule->Umbrella) {
1331 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1332 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001333 HadError = true;
1334 return;
1335 }
1336
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001337 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001338 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001339 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001340 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001341 if (llvm::sys::path::is_absolute(FileName)) {
1342 PathName = FileName;
1343 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001344 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1345 PathName = Dir->getName();
1346 llvm::sys::path::append(PathName, FileName);
1347 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001348 } else {
1349 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001350 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001351 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001352
Douglas Gregord620a842011-12-06 17:16:41 +00001353 if (ActiveModule->isPartOfFramework()) {
1354 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001355
1356 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001357 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001358 llvm::sys::path::append(PathName, FileName);
1359 File = SourceMgr.getFileManager().getFile(PathName);
1360
1361 if (!File) {
1362 // Check whether this file is in the private headers.
1363 PathName.resize(PathLength);
1364 llvm::sys::path::append(PathName, "PrivateHeaders");
1365 llvm::sys::path::append(PathName, FileName);
1366 File = SourceMgr.getFileManager().getFile(PathName);
1367 }
1368 } else {
1369 // Lookup for normal headers.
1370 llvm::sys::path::append(PathName, FileName);
1371 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001372
1373 // If this is a system module with a top-level header, this header
1374 // may have a counterpart (or replacement) in the set of headers
1375 // supplied by Clang. Find that builtin header.
1376 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1377 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001378 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001379 llvm::sys::path::append(BuiltinPathName, FileName);
1380 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1381
1382 // If Clang supplies this header but the underlying system does not,
1383 // just silently swap in our builtin version. Otherwise, we'll end
1384 // up adding both (later).
1385 if (!File && BuiltinFile) {
1386 File = BuiltinFile;
1387 BuiltinFile = 0;
1388 }
1389 }
Douglas Gregord620a842011-12-06 17:16:41 +00001390 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001391 }
Douglas Gregora8654052011-11-17 22:09:43 +00001392
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001393 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1394 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001395 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001396 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001397 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001398 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001399 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001400 } else if (Umbrella) {
1401 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001402 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001403 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001404 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001405 HadError = true;
1406 } else {
1407 // Record this umbrella header.
1408 Map.setUmbrellaHeader(ActiveModule, File);
1409 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001410 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001411 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001412 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001413
1414 // If there is a builtin counterpart to this file, add it now.
1415 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001416 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001417 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001418 } else if (!Exclude) {
1419 // Ignore excluded header files. They're optional anyway.
1420
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001421 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001422 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001423 HadError = true;
1424 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001425}
1426
Douglas Gregor77d029f2011-12-08 19:11:24 +00001427/// \brief Parse an umbrella directory declaration.
1428///
1429/// umbrella-dir-declaration:
1430/// umbrella string-literal
1431void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1432 // Parse the directory name.
1433 if (!Tok.is(MMToken::StringLiteral)) {
1434 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1435 << "umbrella";
1436 HadError = true;
1437 return;
1438 }
1439
1440 std::string DirName = Tok.getString();
1441 SourceLocation DirNameLoc = consumeToken();
1442
1443 // Check whether we already have an umbrella.
1444 if (ActiveModule->Umbrella) {
1445 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1446 << ActiveModule->getFullModuleName();
1447 HadError = true;
1448 return;
1449 }
1450
1451 // Look for this file.
1452 const DirectoryEntry *Dir = 0;
1453 if (llvm::sys::path::is_absolute(DirName))
1454 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1455 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001456 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001457 PathName = Directory->getName();
1458 llvm::sys::path::append(PathName, DirName);
1459 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1460 }
1461
1462 if (!Dir) {
1463 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1464 << DirName;
1465 HadError = true;
1466 return;
1467 }
1468
1469 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1470 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1471 << OwningModule->getFullModuleName();
1472 HadError = true;
1473 return;
1474 }
1475
1476 // Record this umbrella directory.
1477 Map.setUmbrellaDir(ActiveModule, Dir);
1478}
1479
Douglas Gregor90db2602011-12-02 01:47:07 +00001480/// \brief Parse a module export declaration.
1481///
1482/// export-declaration:
1483/// 'export' wildcard-module-id
1484///
1485/// wildcard-module-id:
1486/// identifier
1487/// '*'
1488/// identifier '.' wildcard-module-id
1489void ModuleMapParser::parseExportDecl() {
1490 assert(Tok.is(MMToken::ExportKeyword));
1491 SourceLocation ExportLoc = consumeToken();
1492
1493 // Parse the module-id with an optional wildcard at the end.
1494 ModuleId ParsedModuleId;
1495 bool Wildcard = false;
1496 do {
1497 if (Tok.is(MMToken::Identifier)) {
1498 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1499 Tok.getLocation()));
1500 consumeToken();
1501
1502 if (Tok.is(MMToken::Period)) {
1503 consumeToken();
1504 continue;
1505 }
1506
1507 break;
1508 }
1509
1510 if(Tok.is(MMToken::Star)) {
1511 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001512 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001513 break;
1514 }
1515
1516 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1517 HadError = true;
1518 return;
1519 } while (true);
1520
1521 Module::UnresolvedExportDecl Unresolved = {
1522 ExportLoc, ParsedModuleId, Wildcard
1523 };
1524 ActiveModule->UnresolvedExports.push_back(Unresolved);
1525}
1526
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001527/// \brief Parse a link declaration.
1528///
1529/// module-declaration:
1530/// 'link' 'framework'[opt] string-literal
1531void ModuleMapParser::parseLinkDecl() {
1532 assert(Tok.is(MMToken::LinkKeyword));
1533 SourceLocation LinkLoc = consumeToken();
1534
1535 // Parse the optional 'framework' keyword.
1536 bool IsFramework = false;
1537 if (Tok.is(MMToken::FrameworkKeyword)) {
1538 consumeToken();
1539 IsFramework = true;
1540 }
1541
1542 // Parse the library name
1543 if (!Tok.is(MMToken::StringLiteral)) {
1544 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1545 << IsFramework << SourceRange(LinkLoc);
1546 HadError = true;
1547 return;
1548 }
1549
1550 std::string LibraryName = Tok.getString();
1551 consumeToken();
1552 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1553 IsFramework));
1554}
1555
Douglas Gregor63a72682013-03-20 00:22:05 +00001556/// \brief Parse a configuration macro declaration.
1557///
1558/// module-declaration:
1559/// 'config_macros' attributes[opt] config-macro-list?
1560///
1561/// config-macro-list:
1562/// identifier (',' identifier)?
1563void ModuleMapParser::parseConfigMacros() {
1564 assert(Tok.is(MMToken::ConfigMacros));
1565 SourceLocation ConfigMacrosLoc = consumeToken();
1566
1567 // Only top-level modules can have configuration macros.
1568 if (ActiveModule->Parent) {
1569 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1570 }
1571
1572 // Parse the optional attributes.
1573 Attributes Attrs;
1574 parseOptionalAttributes(Attrs);
1575 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1576 ActiveModule->ConfigMacrosExhaustive = true;
1577 }
1578
1579 // If we don't have an identifier, we're done.
1580 if (!Tok.is(MMToken::Identifier))
1581 return;
1582
1583 // Consume the first identifier.
1584 if (!ActiveModule->Parent) {
1585 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1586 }
1587 consumeToken();
1588
1589 do {
1590 // If there's a comma, consume it.
1591 if (!Tok.is(MMToken::Comma))
1592 break;
1593 consumeToken();
1594
1595 // We expect to see a macro name here.
1596 if (!Tok.is(MMToken::Identifier)) {
1597 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1598 break;
1599 }
1600
1601 // Consume the macro name.
1602 if (!ActiveModule->Parent) {
1603 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1604 }
1605 consumeToken();
1606 } while (true);
1607}
1608
Douglas Gregor906d66a2013-03-20 21:10:35 +00001609/// \brief Format a module-id into a string.
1610static std::string formatModuleId(const ModuleId &Id) {
1611 std::string result;
1612 {
1613 llvm::raw_string_ostream OS(result);
1614
1615 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1616 if (I)
1617 OS << ".";
1618 OS << Id[I].first;
1619 }
1620 }
1621
1622 return result;
1623}
1624
1625/// \brief Parse a conflict declaration.
1626///
1627/// module-declaration:
1628/// 'conflict' module-id ',' string-literal
1629void ModuleMapParser::parseConflict() {
1630 assert(Tok.is(MMToken::Conflict));
1631 SourceLocation ConflictLoc = consumeToken();
1632 Module::UnresolvedConflict Conflict;
1633
1634 // Parse the module-id.
1635 if (parseModuleId(Conflict.Id))
1636 return;
1637
1638 // Parse the ','.
1639 if (!Tok.is(MMToken::Comma)) {
1640 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1641 << SourceRange(ConflictLoc);
1642 return;
1643 }
1644 consumeToken();
1645
1646 // Parse the message.
1647 if (!Tok.is(MMToken::StringLiteral)) {
1648 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1649 << formatModuleId(Conflict.Id);
1650 return;
1651 }
1652 Conflict.Message = Tok.getString().str();
1653 consumeToken();
1654
1655 // Add this unresolved conflict.
1656 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1657}
1658
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001659/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001660///
1661/// module-declaration:
1662/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1663/// { inferred-module-member* }
1664///
1665/// inferred-module-member:
1666/// 'export' '*'
1667/// 'exclude' identifier
1668void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001669 assert(Tok.is(MMToken::Star));
1670 SourceLocation StarLoc = consumeToken();
1671 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001672
Douglas Gregor1e123682011-12-05 22:27:44 +00001673 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001674 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001675 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1676 Failed = true;
1677 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001678
1679 if (ActiveModule) {
1680 // Inferred modules must have umbrella directories.
1681 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1682 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1683 Failed = true;
1684 }
1685
1686 // Check for redefinition of an inferred module.
1687 if (!Failed && ActiveModule->InferSubmodules) {
1688 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1689 if (ActiveModule->InferredSubmoduleLoc.isValid())
1690 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1691 diag::note_mmap_prev_definition);
1692 Failed = true;
1693 }
1694
1695 // Check for the 'framework' keyword, which is not permitted here.
1696 if (Framework) {
1697 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1698 Framework = false;
1699 }
1700 } else if (Explicit) {
1701 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1702 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001703 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001704
Douglas Gregor1e123682011-12-05 22:27:44 +00001705 // If there were any problems with this inferred submodule, skip its body.
1706 if (Failed) {
1707 if (Tok.is(MMToken::LBrace)) {
1708 consumeToken();
1709 skipUntil(MMToken::RBrace);
1710 if (Tok.is(MMToken::RBrace))
1711 consumeToken();
1712 }
1713 HadError = true;
1714 return;
1715 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001716
1717 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001718 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001719 parseOptionalAttributes(Attrs);
1720
1721 if (ActiveModule) {
1722 // Note that we have an inferred submodule.
1723 ActiveModule->InferSubmodules = true;
1724 ActiveModule->InferredSubmoduleLoc = StarLoc;
1725 ActiveModule->InferExplicitSubmodules = Explicit;
1726 } else {
1727 // We'll be inferring framework modules for this directory.
1728 Map.InferredDirectories[Directory].InferModules = true;
1729 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1730 }
1731
Douglas Gregor1e123682011-12-05 22:27:44 +00001732 // Parse the opening brace.
1733 if (!Tok.is(MMToken::LBrace)) {
1734 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1735 HadError = true;
1736 return;
1737 }
1738 SourceLocation LBraceLoc = consumeToken();
1739
1740 // Parse the body of the inferred submodule.
1741 bool Done = false;
1742 do {
1743 switch (Tok.Kind) {
1744 case MMToken::EndOfFile:
1745 case MMToken::RBrace:
1746 Done = true;
1747 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001748
1749 case MMToken::ExcludeKeyword: {
1750 if (ActiveModule) {
1751 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001752 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001753 consumeToken();
1754 break;
1755 }
1756
1757 consumeToken();
1758 if (!Tok.is(MMToken::Identifier)) {
1759 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1760 break;
1761 }
1762
1763 Map.InferredDirectories[Directory].ExcludedModules
1764 .push_back(Tok.getString());
1765 consumeToken();
1766 break;
1767 }
1768
1769 case MMToken::ExportKeyword:
1770 if (!ActiveModule) {
1771 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001772 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001773 consumeToken();
1774 break;
1775 }
1776
Douglas Gregor1e123682011-12-05 22:27:44 +00001777 consumeToken();
1778 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001779 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001780 else
1781 Diags.Report(Tok.getLocation(),
1782 diag::err_mmap_expected_export_wildcard);
1783 consumeToken();
1784 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001785
Douglas Gregor1e123682011-12-05 22:27:44 +00001786 case MMToken::ExplicitKeyword:
1787 case MMToken::ModuleKeyword:
1788 case MMToken::HeaderKeyword:
1789 case MMToken::UmbrellaKeyword:
1790 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001791 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001792 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001793 consumeToken();
1794 break;
1795 }
1796 } while (!Done);
1797
1798 if (Tok.is(MMToken::RBrace))
1799 consumeToken();
1800 else {
1801 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1802 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1803 HadError = true;
1804 }
1805}
1806
Douglas Gregor82e52372012-11-06 19:39:40 +00001807/// \brief Parse optional attributes.
1808///
1809/// attributes:
1810/// attribute attributes
1811/// attribute
1812///
1813/// attribute:
1814/// [ identifier ]
1815///
1816/// \param Attrs Will be filled in with the parsed attributes.
1817///
1818/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001819bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001820 bool HadError = false;
1821
1822 while (Tok.is(MMToken::LSquare)) {
1823 // Consume the '['.
1824 SourceLocation LSquareLoc = consumeToken();
1825
1826 // Check whether we have an attribute name here.
1827 if (!Tok.is(MMToken::Identifier)) {
1828 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1829 skipUntil(MMToken::RSquare);
1830 if (Tok.is(MMToken::RSquare))
1831 consumeToken();
1832 HadError = true;
1833 }
1834
1835 // Decode the attribute name.
1836 AttributeKind Attribute
1837 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001838 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00001839 .Case("system", AT_system)
1840 .Default(AT_unknown);
1841 switch (Attribute) {
1842 case AT_unknown:
1843 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1844 << Tok.getString();
1845 break;
1846
1847 case AT_system:
1848 Attrs.IsSystem = true;
1849 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001850
1851 case AT_exhaustive:
1852 Attrs.IsExhaustive = true;
1853 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001854 }
1855 consumeToken();
1856
1857 // Consume the ']'.
1858 if (!Tok.is(MMToken::RSquare)) {
1859 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1860 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1861 skipUntil(MMToken::RSquare);
1862 HadError = true;
1863 }
1864
1865 if (Tok.is(MMToken::RSquare))
1866 consumeToken();
1867 }
1868
1869 return HadError;
1870}
1871
Douglas Gregor6a1db482011-12-09 02:04:43 +00001872/// \brief If there is a specific header search directory due the presence
1873/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1874const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1875 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1876 // If we have an umbrella directory, use that.
1877 if (Mod->hasUmbrellaDir())
1878 return Mod->getUmbrellaDir();
1879
1880 // If we have a framework directory, stop looking.
1881 if (Mod->IsFramework)
1882 return 0;
1883 }
1884
1885 return 0;
1886}
1887
Douglas Gregora30cfe52011-11-11 19:10:28 +00001888/// \brief Parse a module map file.
1889///
1890/// module-map-file:
1891/// module-declaration*
1892bool ModuleMapParser::parseModuleMapFile() {
1893 do {
1894 switch (Tok.Kind) {
1895 case MMToken::EndOfFile:
1896 return HadError;
1897
Douglas Gregor587986e2011-12-07 02:23:45 +00001898 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001899 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001900 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001901 parseModuleDecl();
1902 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001903
Douglas Gregor51f564f2011-12-31 04:05:44 +00001904 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00001905 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00001906 case MMToken::Conflict:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001907 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001908 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001909 case MMToken::HeaderKeyword:
1910 case MMToken::Identifier:
1911 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001912 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001913 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001914 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001915 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001916 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001917 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001918 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001919 case MMToken::StringLiteral:
1920 case MMToken::UmbrellaKeyword:
1921 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1922 HadError = true;
1923 consumeToken();
1924 break;
1925 }
1926 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001927}
1928
1929bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001930 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1931 = ParsedModuleMap.find(File);
1932 if (Known != ParsedModuleMap.end())
1933 return Known->second;
1934
Douglas Gregordc58aa72012-01-30 06:01:29 +00001935 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001936 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1937 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1938 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001939 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001940
1941 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001942 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1943 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001944 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001945 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001946 bool Result = Parser.parseModuleMapFile();
1947 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001948 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001949 return Result;
1950}