blob: b2698b1877d657d0971639412956c7d3d0d647aa [file] [log] [blame]
Douglas Gregora30cfe52011-11-11 19:10:28 +00001//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ModuleMap implementation, which describes the layout
11// of a module as it relates to headers.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/Lex/ModuleMap.h"
Jordan Rose3f6f51e2013-02-08 22:30:41 +000015#include "clang/Basic/CharInfo.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000016#include "clang/Basic/Diagnostic.h"
Douglas Gregor02c23eb2012-10-23 22:26:28 +000017#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000018#include "clang/Basic/FileManager.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Basic/TargetOptions.h"
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000021#include "clang/Lex/HeaderSearch.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000022#include "clang/Lex/LexDiagnostic.h"
23#include "clang/Lex/Lexer.h"
24#include "clang/Lex/LiteralSupport.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/ADT/StringSwitch.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000027#include "llvm/Support/Allocator.h"
Douglas Gregorac252a32011-12-06 19:39:29 +000028#include "llvm/Support/FileSystem.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000029#include "llvm/Support/Host.h"
Rafael Espindola8229d222013-06-11 22:15:02 +000030#include "llvm/Support/Path.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000031#include "llvm/Support/raw_ostream.h"
Douglas Gregor98cfcbf2012-09-27 14:50:15 +000032#include <stdlib.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000033#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoadeb7822013-01-26 16:29:36 +000034#include <limits.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000035#endif
Douglas Gregora30cfe52011-11-11 19:10:28 +000036using namespace clang;
37
Douglas Gregor90db2602011-12-02 01:47:07 +000038Module::ExportDecl
39ModuleMap::resolveExport(Module *Mod,
40 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +000041 bool Complain) const {
Douglas Gregor0adaa882011-12-05 17:28:06 +000042 // We may have just a wildcard.
43 if (Unresolved.Id.empty()) {
44 assert(Unresolved.Wildcard && "Invalid unresolved export");
45 return Module::ExportDecl(0, true);
46 }
47
Douglas Gregor906d66a2013-03-20 21:10:35 +000048 // Resolve the module-id.
49 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
50 if (!Context)
51 return Module::ExportDecl();
52
53 return Module::ExportDecl(Context, Unresolved.Wildcard);
54}
55
56Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
57 bool Complain) const {
Douglas Gregor90db2602011-12-02 01:47:07 +000058 // Find the starting module.
Douglas Gregor906d66a2013-03-20 21:10:35 +000059 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor90db2602011-12-02 01:47:07 +000060 if (!Context) {
61 if (Complain)
Douglas Gregor906d66a2013-03-20 21:10:35 +000062 Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
63 << Id[0].first << Mod->getFullModuleName();
64
65 return 0;
Douglas Gregor90db2602011-12-02 01:47:07 +000066 }
67
68 // Dig into the module path.
Douglas Gregor906d66a2013-03-20 21:10:35 +000069 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
70 Module *Sub = lookupModuleQualified(Id[I].first, Context);
Douglas Gregor90db2602011-12-02 01:47:07 +000071 if (!Sub) {
72 if (Complain)
Douglas Gregor906d66a2013-03-20 21:10:35 +000073 Diags->Report(Id[I].second, diag::err_mmap_missing_module_qualified)
74 << Id[I].first << Context->getFullModuleName()
75 << SourceRange(Id[0].second, Id[I-1].second);
76
77 return 0;
Douglas Gregor90db2602011-12-02 01:47:07 +000078 }
Douglas Gregor906d66a2013-03-20 21:10:35 +000079
Douglas Gregor90db2602011-12-02 01:47:07 +000080 Context = Sub;
81 }
Douglas Gregor906d66a2013-03-20 21:10:35 +000082
83 return Context;
Douglas Gregor90db2602011-12-02 01:47:07 +000084}
85
Douglas Gregora4a90ca2013-05-03 22:58:43 +000086ModuleMap::ModuleMap(FileManager &FileMgr, DiagnosticConsumer &DC,
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000087 const LangOptions &LangOpts, const TargetInfo *Target,
88 HeaderSearch &HeaderInfo)
89 : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +000090 BuiltinIncludeDir(0), CompilingModule(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000091{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000092 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
93 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000094 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora4a90ca2013-05-03 22:58:43 +000095 Diags->setClient(new ForwardingDiagnosticConsumer(DC),
96 /*ShouldOwnClient=*/true);
Douglas Gregora30cfe52011-11-11 19:10:28 +000097 SourceMgr = new SourceManager(*Diags, FileMgr);
98}
99
100ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +0000101 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
102 IEnd = Modules.end();
103 I != IEnd; ++I) {
104 delete I->getValue();
105 }
106
Douglas Gregora30cfe52011-11-11 19:10:28 +0000107 delete SourceMgr;
108}
109
Douglas Gregordc58aa72012-01-30 06:01:29 +0000110void ModuleMap::setTarget(const TargetInfo &Target) {
111 assert((!this->Target || this->Target == &Target) &&
112 "Improper target override");
113 this->Target = &Target;
114}
115
Douglas Gregor8b48e082012-10-12 21:15:50 +0000116/// \brief "Sanitize" a filename so that it can be used as an identifier.
117static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
118 SmallVectorImpl<char> &Buffer) {
119 if (Name.empty())
120 return Name;
121
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000122 if (!isValidIdentifier(Name)) {
Douglas Gregor8b48e082012-10-12 21:15:50 +0000123 // If we don't already have something with the form of an identifier,
124 // create a buffer with the sanitized name.
125 Buffer.clear();
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000126 if (isDigit(Name[0]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000127 Buffer.push_back('_');
128 Buffer.reserve(Buffer.size() + Name.size());
129 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000130 if (isIdentifierBody(Name[I]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000131 Buffer.push_back(Name[I]);
132 else
133 Buffer.push_back('_');
134 }
135
136 Name = StringRef(Buffer.data(), Buffer.size());
137 }
138
139 while (llvm::StringSwitch<bool>(Name)
140#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
141#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
142#include "clang/Basic/TokenKinds.def"
143 .Default(false)) {
144 if (Name.data() != Buffer.data())
145 Buffer.append(Name.begin(), Name.end());
146 Buffer.push_back('_');
147 Name = StringRef(Buffer.data(), Buffer.size());
148 }
149
150 return Name;
151}
152
Douglas Gregordb3910b2013-05-02 17:58:30 +0000153/// \brief Determine whether the given file name is the name of a builtin
154/// header, supplied by Clang to replace, override, or augment existing system
155/// headers.
156static bool isBuiltinHeader(StringRef FileName) {
157 return llvm::StringSwitch<bool>(FileName)
158 .Case("float.h", true)
159 .Case("iso646.h", true)
160 .Case("limits.h", true)
161 .Case("stdalign.h", true)
162 .Case("stdarg.h", true)
163 .Case("stdbool.h", true)
164 .Case("stddef.h", true)
165 .Case("stdint.h", true)
166 .Case("tgmath.h", true)
167 .Case("unwind.h", true)
168 .Default(false);
169}
170
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000171ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000172 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000173 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000174 // If a header is not available, don't report that it maps to anything.
175 if (!Known->second.isAvailable())
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000176 return KnownHeader();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000177
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000178 return Known->second;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000179 }
Douglas Gregordb3910b2013-05-02 17:58:30 +0000180
181 // If we've found a builtin header within Clang's builtin include directory,
182 // load all of the module maps to see if it will get associated with a
183 // specific module (e.g., in /usr/include).
184 if (File->getDir() == BuiltinIncludeDir &&
185 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
Douglas Gregor30a16f12013-05-10 22:52:27 +0000186 HeaderInfo.loadTopLevelSystemModules();
Douglas Gregordb3910b2013-05-02 17:58:30 +0000187
188 // Check again.
189 Known = Headers.find(File);
190 if (Known != Headers.end()) {
191 // If a header is not available, don't report that it maps to anything.
192 if (!Known->second.isAvailable())
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000193 return KnownHeader();
Douglas Gregordb3910b2013-05-02 17:58:30 +0000194
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000195 return Known->second;
Douglas Gregordb3910b2013-05-02 17:58:30 +0000196 }
197 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000198
Douglas Gregoradb97992011-11-16 23:02:25 +0000199 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000200 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000201
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000202 // Note: as an egregious but useful hack we use the real path here, because
203 // frameworks moving from top-level frameworks to embedded frameworks tend
204 // to be symlinked from the top-level location to the embedded location,
205 // and we need to resolve lookups as if we had found the embedded location.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000206 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000207
208 // Keep walking up the directory hierarchy, looking for a directory with
209 // an umbrella header.
210 do {
211 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
212 = UmbrellaDirs.find(Dir);
213 if (KnownDir != UmbrellaDirs.end()) {
214 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000215
216 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000217 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000218 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000219 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000220 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000221
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000222 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000223 // Infer submodules for each of the directories we found between
224 // the directory of the umbrella header and the directory where
225 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000226 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000227
Douglas Gregor6a1db482011-12-09 02:04:43 +0000228 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000229 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000230 SmallString<32> NameBuf;
231 StringRef Name = sanitizeFilenameAsIdentifier(
232 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
233 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000234 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000235 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000236
237 // Associate the module and the directory.
238 UmbrellaDirs[SkippedDirs[I-1]] = Result;
239
240 // If inferred submodules export everything they import, add a
241 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000242 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000243 Result->Exports.push_back(Module::ExportDecl(0, true));
244 }
245
246 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000247 SmallString<32> NameBuf;
248 StringRef Name = sanitizeFilenameAsIdentifier(
249 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000250 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000251 Explicit).first;
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +0000252 Result->addTopHeader(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000253
254 // If inferred submodules export everything they import, add a
255 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000256 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000257 Result->Exports.push_back(Module::ExportDecl(0, true));
258 } else {
259 // Record each of the directories we stepped through as being part of
260 // the module we found, since the umbrella header covers them all.
261 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
262 UmbrellaDirs[SkippedDirs[I]] = Result;
263 }
264
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000265 Headers[File] = KnownHeader(Result, NormalHeader);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000266
267 // If a header corresponds to an unavailable module, don't report
268 // that it maps to anything.
269 if (!Result->isAvailable())
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000270 return KnownHeader();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000271
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000272 return Headers[File];
Douglas Gregore209e502011-12-06 01:10:29 +0000273 }
274
275 SkippedDirs.push_back(Dir);
276
Douglas Gregoradb97992011-11-16 23:02:25 +0000277 // Retrieve our parent path.
278 DirName = llvm::sys::path::parent_path(DirName);
279 if (DirName.empty())
280 break;
281
282 // Resolve the parent path to a directory entry.
283 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000284 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000285
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000286 return KnownHeader();
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000287}
288
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000289bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
290 HeadersMap::const_iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000291 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000292 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000293
294 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000295 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000296 StringRef DirName = Dir->getName();
297
298 // Keep walking up the directory hierarchy, looking for a directory with
299 // an umbrella header.
300 do {
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000301 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor51f564f2011-12-31 04:05:44 +0000302 = UmbrellaDirs.find(Dir);
303 if (KnownDir != UmbrellaDirs.end()) {
304 Module *Found = KnownDir->second;
305 if (!Found->isAvailable())
306 return true;
307
308 // Search up the module stack until we find a module with an umbrella
309 // directory.
310 Module *UmbrellaModule = Found;
311 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
312 UmbrellaModule = UmbrellaModule->Parent;
313
314 if (UmbrellaModule->InferSubmodules) {
315 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
316 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000317 SmallString<32> NameBuf;
318 StringRef Name = sanitizeFilenameAsIdentifier(
319 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
320 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000321 Found = lookupModuleQualified(Name, Found);
322 if (!Found)
323 return false;
324 if (!Found->isAvailable())
325 return true;
326 }
327
328 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000329 SmallString<32> NameBuf;
330 StringRef Name = sanitizeFilenameAsIdentifier(
331 llvm::sys::path::stem(Header->getName()),
332 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000333 Found = lookupModuleQualified(Name, Found);
334 if (!Found)
335 return false;
336 }
337
338 return !Found->isAvailable();
339 }
340
341 SkippedDirs.push_back(Dir);
342
343 // Retrieve our parent path.
344 DirName = llvm::sys::path::parent_path(DirName);
345 if (DirName.empty())
346 break;
347
348 // Resolve the parent path to a directory entry.
349 Dir = SourceMgr->getFileManager().getDirectory(DirName);
350 } while (Dir);
351
352 return false;
353}
354
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000355Module *ModuleMap::findModule(StringRef Name) const {
356 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor484535e2011-11-11 23:20:24 +0000357 if (Known != Modules.end())
358 return Known->getValue();
359
360 return 0;
361}
362
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000363Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
364 Module *Context) const {
Douglas Gregor90db2602011-12-02 01:47:07 +0000365 for(; Context; Context = Context->Parent) {
366 if (Module *Sub = lookupModuleQualified(Name, Context))
367 return Sub;
368 }
369
370 return findModule(Name);
371}
372
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000373Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor90db2602011-12-02 01:47:07 +0000374 if (!Context)
375 return findModule(Name);
376
Douglas Gregorb7a78192012-01-04 23:32:19 +0000377 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000378}
379
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000380std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000381ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
382 bool IsExplicit) {
383 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000384 if (Module *Sub = lookupModuleQualified(Name, Parent))
385 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000386
387 // Create a new module with this name.
388 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
389 IsExplicit);
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000390 if (!Parent) {
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000391 Modules[Name] = Result;
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000392 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
393 Name == LangOpts.CurrentModule) {
394 CompilingModule = Result;
395 }
396 }
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000397 return std::make_pair(Result, true);
398}
399
Douglas Gregor82e52372012-11-06 19:39:40 +0000400bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000401 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000402 // Check whether we have already looked into the parent directory
403 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000404 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000405 inferred = InferredDirectories.find(ParentDir);
406 if (inferred == InferredDirectories.end())
407 return false;
408
409 if (!inferred->second.InferModules)
410 return false;
411
412 // We're allowed to infer for this directory, but make sure it's okay
413 // to infer this particular module.
414 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
415 inferred->second.ExcludedModules.end(),
416 Name) == inferred->second.ExcludedModules.end();
417
418 if (canInfer && inferred->second.InferSystemModules)
419 IsSystem = true;
420
421 return canInfer;
422}
423
Douglas Gregor8767dc22013-01-14 17:57:51 +0000424/// \brief For a framework module, infer the framework against which we
425/// should link.
426static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
427 FileManager &FileMgr) {
428 assert(Mod->IsFramework && "Can only infer linking for framework modules");
429 assert(!Mod->isSubFramework() &&
430 "Can only infer linking for top-level frameworks");
431
432 SmallString<128> LibName;
433 LibName += FrameworkDir->getName();
434 llvm::sys::path::append(LibName, Mod->Name);
435 if (FileMgr.getFile(LibName)) {
436 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
437 /*IsFramework=*/true));
438 }
439}
440
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000441Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000442ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000443 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000444 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000445 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000446 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000447 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
448 return Mod;
449
450 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000451
452 // If the framework has a parent path from which we're allowed to infer
453 // a framework module, do so.
454 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000455 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000456
Douglas Gregor7005b902013-01-10 01:43:00 +0000457 // Note: as an egregious but useful hack we use the real path here, because
458 // we might be looking at an embedded framework that symlinks out to a
459 // top-level framework, and we need to infer as if we were naming the
460 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000461 StringRef FrameworkDirName
462 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000463
Douglas Gregor82e52372012-11-06 19:39:40 +0000464 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000465 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000466 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000467 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000468 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
469 // Check whether we have already looked into the parent directory
470 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000471 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000472 inferred = InferredDirectories.find(ParentDir);
473 if (inferred == InferredDirectories.end()) {
474 // We haven't looked here before. Load a module map, if there is
475 // one.
476 SmallString<128> ModMapPath = Parent;
477 llvm::sys::path::append(ModMapPath, "module.map");
478 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000479 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor82e52372012-11-06 19:39:40 +0000480 inferred = InferredDirectories.find(ParentDir);
481 }
482
483 if (inferred == InferredDirectories.end())
484 inferred = InferredDirectories.insert(
485 std::make_pair(ParentDir, InferredDirectory())).first;
486 }
487
488 if (inferred->second.InferModules) {
489 // We're allowed to infer for this directory, but make sure it's okay
490 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000491 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000492 canInfer = std::find(inferred->second.ExcludedModules.begin(),
493 inferred->second.ExcludedModules.end(),
494 Name) == inferred->second.ExcludedModules.end();
495
496 if (inferred->second.InferSystemModules)
497 IsSystem = true;
498 }
499 }
500 }
501
502 // If we're not allowed to infer a framework module, don't.
503 if (!canInfer)
504 return 0;
505 }
506
507
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000508 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000509 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramerceb6dc82013-06-28 16:25:46 +0000510 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000511 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000512
513 // FIXME: If there's no umbrella header, we could probably scan the
514 // framework to load *everything*. But, it's not clear that this is a good
515 // idea.
516 if (!UmbrellaHeader)
517 return 0;
518
Douglas Gregorac252a32011-12-06 19:39:29 +0000519 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
520 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000521 if (IsSystem)
522 Result->IsSystem = IsSystem;
523
Douglas Gregorb7a78192012-01-04 23:32:19 +0000524 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000525 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000526
Douglas Gregor489ad432011-12-08 18:00:48 +0000527 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000528 Result->Umbrella = UmbrellaHeader;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000529 Headers[UmbrellaHeader] = KnownHeader(Result, NormalHeader);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000530 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000531
532 // export *
533 Result->Exports.push_back(Module::ExportDecl(0, true));
534
Douglas Gregore209e502011-12-06 01:10:29 +0000535 // module * { export * }
536 Result->InferSubmodules = true;
537 Result->InferExportWildcard = true;
538
Douglas Gregorac252a32011-12-06 19:39:29 +0000539 // Look for subframeworks.
540 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000541 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000542 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000543 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000544 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000545 llvm::sys::path::native(SubframeworksDirName.str(),
546 SubframeworksDirNameNative);
547 for (llvm::sys::fs::directory_iterator
548 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000549 Dir != DirEnd && !EC; Dir.increment(EC)) {
550 if (!StringRef(Dir->path()).endswith(".framework"))
551 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000552
Douglas Gregorac252a32011-12-06 19:39:29 +0000553 if (const DirectoryEntry *SubframeworkDir
554 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000555 // Note: as an egregious but useful hack, we use the real path here and
556 // check whether it is actually a subdirectory of the parent directory.
557 // This will not be the case if the 'subframework' is actually a symlink
558 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000559 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
560 bool FoundParent = false;
561 do {
562 // Get the parent directory name.
563 SubframeworkDirName
564 = llvm::sys::path::parent_path(SubframeworkDirName);
565 if (SubframeworkDirName.empty())
566 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000567
Douglas Gregor713b7c02013-01-26 00:55:12 +0000568 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
569 FoundParent = true;
570 break;
571 }
572 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000573
Douglas Gregor713b7c02013-01-26 00:55:12 +0000574 if (!FoundParent)
575 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000576
Douglas Gregorac252a32011-12-06 19:39:29 +0000577 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000578 SmallString<32> NameBuf;
579 inferFrameworkModule(sanitizeFilenameAsIdentifier(
580 llvm::sys::path::stem(Dir->path()), NameBuf),
581 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000582 }
583 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000584
Douglas Gregor8767dc22013-01-14 17:57:51 +0000585 // If the module is a top-level framework, automatically link against the
586 // framework.
587 if (!Result->isSubFramework()) {
588 inferFrameworkLink(Result, FrameworkDir, FileMgr);
589 }
590
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000591 return Result;
592}
593
Douglas Gregore209e502011-12-06 01:10:29 +0000594void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000595 Headers[UmbrellaHeader] = KnownHeader(Mod, NormalHeader);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000596 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000597 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000598}
599
Douglas Gregor77d029f2011-12-08 19:11:24 +0000600void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
601 Mod->Umbrella = UmbrellaDir;
602 UmbrellaDirs[UmbrellaDir] = Mod;
603}
604
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000605void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000606 ModuleHeaderRole Role) {
607 if (Role == ExcludedHeader) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000608 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000609 } else {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000610 if (Role == PrivateHeader)
611 Mod->PrivateHeaders.push_back(Header);
612 else
613 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000614 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000615 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000616 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000617 Headers[Header] = KnownHeader(Mod, Role);
Douglas Gregore209e502011-12-06 01:10:29 +0000618}
619
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000620const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000621ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000622 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
623 return 0;
624
625 return SourceMgr->getFileEntryForID(
626 SourceMgr->getFileID(Module->DefinitionLoc));
627}
628
Douglas Gregora30cfe52011-11-11 19:10:28 +0000629void ModuleMap::dump() {
630 llvm::errs() << "Modules:";
631 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
632 MEnd = Modules.end();
633 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000634 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000635
636 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000637 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000638 H != HEnd; ++H) {
639 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000640 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000641 }
642}
643
Douglas Gregor90db2602011-12-02 01:47:07 +0000644bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
645 bool HadError = false;
646 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
647 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
648 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000649 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000650 Mod->Exports.push_back(Export);
651 else
652 HadError = true;
653 }
654 Mod->UnresolvedExports.clear();
655 return HadError;
656}
657
Douglas Gregor906d66a2013-03-20 21:10:35 +0000658bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
659 bool HadError = false;
660 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
661 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
662 Mod, Complain);
663 if (!OtherMod) {
664 HadError = true;
665 continue;
666 }
667
668 Module::Conflict Conflict;
669 Conflict.Other = OtherMod;
670 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
671 Mod->Conflicts.push_back(Conflict);
672 }
673 Mod->UnresolvedConflicts.clear();
674 return HadError;
675}
676
Douglas Gregor55988682011-12-05 16:33:54 +0000677Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
678 if (Loc.isInvalid())
679 return 0;
680
681 // Use the expansion location to determine which module we're in.
682 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
683 if (!ExpansionLoc.isFileID())
684 return 0;
685
686
687 const SourceManager &SrcMgr = Loc.getManager();
688 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000689
Douglas Gregor303aae92012-01-06 17:19:32 +0000690 while (const FileEntry *ExpansionFile
691 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
692 // Find the module that owns this header (if any).
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000693 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor303aae92012-01-06 17:19:32 +0000694 return Mod;
695
696 // No module owns this header, so look up the inclusion chain to see if
697 // any included header has an associated module.
698 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
699 if (IncludeLoc.isInvalid())
700 return 0;
701
702 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
703 }
704
705 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000706}
707
Douglas Gregora30cfe52011-11-11 19:10:28 +0000708//----------------------------------------------------------------------------//
709// Module map file parser
710//----------------------------------------------------------------------------//
711
712namespace clang {
713 /// \brief A token in a module map file.
714 struct MMToken {
715 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000716 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000717 ConfigMacros,
Douglas Gregor906d66a2013-03-20 21:10:35 +0000718 Conflict,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000719 EndOfFile,
720 HeaderKeyword,
721 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000722 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000723 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000724 ExportKeyword,
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000725 ExternKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000726 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000727 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000728 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000729 Period,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000730 PrivateKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000731 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000732 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000733 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000734 StringLiteral,
735 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000736 RBrace,
737 LSquare,
738 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000739 } Kind;
740
741 unsigned Location;
742 unsigned StringLength;
743 const char *StringData;
744
745 void clear() {
746 Kind = EndOfFile;
747 Location = 0;
748 StringLength = 0;
749 StringData = 0;
750 }
751
752 bool is(TokenKind K) const { return Kind == K; }
753
754 SourceLocation getLocation() const {
755 return SourceLocation::getFromRawEncoding(Location);
756 }
757
758 StringRef getString() const {
759 return StringRef(StringData, StringLength);
760 }
761 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000762
763 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000764 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000765 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000766
767 /// \brief Whether this is a system module.
768 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000769
770 /// \brief Whether this is an exhaustive set of configuration macros.
771 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000772 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000773
Douglas Gregor82e52372012-11-06 19:39:40 +0000774
Douglas Gregora30cfe52011-11-11 19:10:28 +0000775 class ModuleMapParser {
776 Lexer &L;
777 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000778
779 /// \brief Default target information, used only for string literal
780 /// parsing.
781 const TargetInfo *Target;
782
Douglas Gregora30cfe52011-11-11 19:10:28 +0000783 DiagnosticsEngine &Diags;
784 ModuleMap &Map;
785
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000786 /// \brief The directory that this module map resides in.
787 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000788
789 /// \brief The directory containing Clang-supplied headers.
790 const DirectoryEntry *BuiltinIncludeDir;
791
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000792 /// \brief Whether this module map is in a system header directory.
793 bool IsSystem;
794
Douglas Gregora30cfe52011-11-11 19:10:28 +0000795 /// \brief Whether an error occurred.
796 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000797
Douglas Gregora30cfe52011-11-11 19:10:28 +0000798 /// \brief Stores string data for the various string literals referenced
799 /// during parsing.
800 llvm::BumpPtrAllocator StringData;
801
802 /// \brief The current token.
803 MMToken Tok;
804
805 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000806 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000807
808 /// \brief Consume the current token and return its location.
809 SourceLocation consumeToken();
810
811 /// \brief Skip tokens until we reach the a token with the given kind
812 /// (or the end of the file).
813 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000814
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000815 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000816 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000817 void parseModuleDecl();
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000818 void parseExternModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000819 void parseRequiresDecl();
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000820 void parseHeaderDecl(clang::MMToken::TokenKind,
821 SourceLocation LeadingLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000822 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000823 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000824 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000825 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000826 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000827 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000828 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000829
Douglas Gregor6a1db482011-12-09 02:04:43 +0000830 const DirectoryEntry *getOverriddenHeaderSearchDir();
831
Douglas Gregora30cfe52011-11-11 19:10:28 +0000832 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000833 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000834 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000835 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000836 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000837 const DirectoryEntry *Directory,
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000838 const DirectoryEntry *BuiltinIncludeDir,
839 bool IsSystem)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000840 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000841 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
842 IsSystem(IsSystem), HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000843 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000844 Tok.clear();
845 consumeToken();
846 }
847
848 bool parseModuleMapFile();
849 };
850}
851
852SourceLocation ModuleMapParser::consumeToken() {
853retry:
854 SourceLocation Result = Tok.getLocation();
855 Tok.clear();
856
857 Token LToken;
858 L.LexFromRawLexer(LToken);
859 Tok.Location = LToken.getLocation().getRawEncoding();
860 switch (LToken.getKind()) {
861 case tok::raw_identifier:
862 Tok.StringData = LToken.getRawIdentifierData();
863 Tok.StringLength = LToken.getLength();
864 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000865 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000866 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000867 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000868 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000869 .Case("export", MMToken::ExportKeyword)
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000870 .Case("extern", MMToken::ExternKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000871 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000872 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000873 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000874 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000875 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000876 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000877 .Case("umbrella", MMToken::UmbrellaKeyword)
878 .Default(MMToken::Identifier);
879 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000880
881 case tok::comma:
882 Tok.Kind = MMToken::Comma;
883 break;
884
Douglas Gregora30cfe52011-11-11 19:10:28 +0000885 case tok::eof:
886 Tok.Kind = MMToken::EndOfFile;
887 break;
888
889 case tok::l_brace:
890 Tok.Kind = MMToken::LBrace;
891 break;
892
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000893 case tok::l_square:
894 Tok.Kind = MMToken::LSquare;
895 break;
896
Douglas Gregor90db2602011-12-02 01:47:07 +0000897 case tok::period:
898 Tok.Kind = MMToken::Period;
899 break;
900
Douglas Gregora30cfe52011-11-11 19:10:28 +0000901 case tok::r_brace:
902 Tok.Kind = MMToken::RBrace;
903 break;
904
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000905 case tok::r_square:
906 Tok.Kind = MMToken::RSquare;
907 break;
908
Douglas Gregor90db2602011-12-02 01:47:07 +0000909 case tok::star:
910 Tok.Kind = MMToken::Star;
911 break;
912
Douglas Gregora30cfe52011-11-11 19:10:28 +0000913 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000914 if (LToken.hasUDSuffix()) {
915 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
916 HadError = true;
917 goto retry;
918 }
919
Douglas Gregora30cfe52011-11-11 19:10:28 +0000920 // Parse the string literal.
921 LangOptions LangOpts;
922 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
923 if (StringLiteral.hadError)
924 goto retry;
925
926 // Copy the string literal into our string data allocator.
927 unsigned Length = StringLiteral.GetStringLength();
928 char *Saved = StringData.Allocate<char>(Length + 1);
929 memcpy(Saved, StringLiteral.GetString().data(), Length);
930 Saved[Length] = 0;
931
932 // Form the token.
933 Tok.Kind = MMToken::StringLiteral;
934 Tok.StringData = Saved;
935 Tok.StringLength = Length;
936 break;
937 }
938
939 case tok::comment:
940 goto retry;
941
942 default:
943 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
944 HadError = true;
945 goto retry;
946 }
947
948 return Result;
949}
950
951void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
952 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000953 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000954 do {
955 switch (Tok.Kind) {
956 case MMToken::EndOfFile:
957 return;
958
959 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000960 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000961 return;
962
963 ++braceDepth;
964 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000965
966 case MMToken::LSquare:
967 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
968 return;
969
970 ++squareDepth;
971 break;
972
Douglas Gregora30cfe52011-11-11 19:10:28 +0000973 case MMToken::RBrace:
974 if (braceDepth > 0)
975 --braceDepth;
976 else if (Tok.is(K))
977 return;
978 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000979
980 case MMToken::RSquare:
981 if (squareDepth > 0)
982 --squareDepth;
983 else if (Tok.is(K))
984 return;
985 break;
986
Douglas Gregora30cfe52011-11-11 19:10:28 +0000987 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000988 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000989 return;
990 break;
991 }
992
993 consumeToken();
994 } while (true);
995}
996
Douglas Gregor587986e2011-12-07 02:23:45 +0000997/// \brief Parse a module-id.
998///
999/// module-id:
1000/// identifier
1001/// identifier '.' module-id
1002///
1003/// \returns true if an error occurred, false otherwise.
1004bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1005 Id.clear();
1006 do {
1007 if (Tok.is(MMToken::Identifier)) {
1008 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1009 consumeToken();
1010 } else {
1011 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1012 return true;
1013 }
1014
1015 if (!Tok.is(MMToken::Period))
1016 break;
1017
1018 consumeToken();
1019 } while (true);
1020
1021 return false;
1022}
1023
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001024namespace {
1025 /// \brief Enumerates the known attributes.
1026 enum AttributeKind {
1027 /// \brief An unknown attribute.
1028 AT_unknown,
1029 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001030 AT_system,
1031 /// \brief The 'exhaustive' attribute.
1032 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001033 };
1034}
1035
Douglas Gregora30cfe52011-11-11 19:10:28 +00001036/// \brief Parse a module declaration.
1037///
1038/// module-declaration:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001039/// 'extern' 'module' module-id string-literal
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001040/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1041/// { module-member* }
1042///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001043/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001044/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001045/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001046/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001047/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001048/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001049///
1050/// submodule-declaration:
1051/// module-declaration
1052/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001053void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001054 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001055 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1056 if (Tok.is(MMToken::ExternKeyword)) {
1057 parseExternModuleDecl();
1058 return;
1059 }
1060
Douglas Gregord620a842011-12-06 17:16:41 +00001061 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001062 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001063 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001064 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001065
Douglas Gregord620a842011-12-06 17:16:41 +00001066 // Parse 'explicit' keyword, if present.
1067 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001068 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001069 Explicit = true;
1070 }
1071
1072 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001073 if (Tok.is(MMToken::FrameworkKeyword)) {
1074 consumeToken();
1075 Framework = true;
1076 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001077
1078 // Parse 'module' keyword.
1079 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001080 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001081 consumeToken();
1082 HadError = true;
1083 return;
1084 }
1085 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001086
1087 // If we have a wildcard for the module name, this is an inferred submodule.
1088 // Parse it.
1089 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001090 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001091
1092 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001093 ModuleId Id;
1094 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001095 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001096 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001097 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001098
Douglas Gregor587986e2011-12-07 02:23:45 +00001099 if (ActiveModule) {
1100 if (Id.size() > 1) {
1101 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1102 << SourceRange(Id.front().second, Id.back().second);
1103
1104 HadError = true;
1105 return;
1106 }
1107 } else if (Id.size() == 1 && Explicit) {
1108 // Top-level modules can't be explicit.
1109 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1110 Explicit = false;
1111 ExplicitLoc = SourceLocation();
1112 HadError = true;
1113 }
1114
1115 Module *PreviousActiveModule = ActiveModule;
1116 if (Id.size() > 1) {
1117 // This module map defines a submodule. Go find the module of which it
1118 // is a submodule.
1119 ActiveModule = 0;
1120 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1121 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1122 ActiveModule = Next;
1123 continue;
1124 }
1125
1126 if (ActiveModule) {
1127 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1128 << Id[I].first << ActiveModule->getTopLevelModule();
1129 } else {
1130 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1131 }
1132 HadError = true;
1133 return;
1134 }
1135 }
1136
1137 StringRef ModuleName = Id.back().first;
1138 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001139
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001140 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001141 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001142 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001143
Douglas Gregora30cfe52011-11-11 19:10:28 +00001144 // Parse the opening brace.
1145 if (!Tok.is(MMToken::LBrace)) {
1146 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1147 << ModuleName;
1148 HadError = true;
1149 return;
1150 }
1151 SourceLocation LBraceLoc = consumeToken();
1152
1153 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001154 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001155 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1156 // Skip the module definition.
1157 skipUntil(MMToken::RBrace);
1158 if (Tok.is(MMToken::RBrace))
1159 consumeToken();
1160 else {
1161 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1162 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1163 HadError = true;
1164 }
1165 return;
1166 }
1167
Douglas Gregora30cfe52011-11-11 19:10:28 +00001168 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1169 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001170 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001171
1172 // Skip the module definition.
1173 skipUntil(MMToken::RBrace);
1174 if (Tok.is(MMToken::RBrace))
1175 consumeToken();
1176
1177 HadError = true;
1178 return;
1179 }
1180
1181 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001182 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1183 Explicit).first;
1184 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001185 if (Attrs.IsSystem || IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001186 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001187
1188 bool Done = false;
1189 do {
1190 switch (Tok.Kind) {
1191 case MMToken::EndOfFile:
1192 case MMToken::RBrace:
1193 Done = true;
1194 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001195
1196 case MMToken::ConfigMacros:
1197 parseConfigMacros();
1198 break;
1199
Douglas Gregor906d66a2013-03-20 21:10:35 +00001200 case MMToken::Conflict:
1201 parseConflict();
1202 break;
1203
Douglas Gregora30cfe52011-11-11 19:10:28 +00001204 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001205 case MMToken::ExternKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001206 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001207 case MMToken::ModuleKeyword:
1208 parseModuleDecl();
1209 break;
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001210
Douglas Gregor90db2602011-12-02 01:47:07 +00001211 case MMToken::ExportKeyword:
1212 parseExportDecl();
1213 break;
1214
Douglas Gregor51f564f2011-12-31 04:05:44 +00001215 case MMToken::RequiresKeyword:
1216 parseRequiresDecl();
1217 break;
1218
Douglas Gregor77d029f2011-12-08 19:11:24 +00001219 case MMToken::UmbrellaKeyword: {
1220 SourceLocation UmbrellaLoc = consumeToken();
1221 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001222 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +00001223 else
1224 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001225 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001226 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001227
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001228 case MMToken::ExcludeKeyword: {
1229 SourceLocation ExcludeLoc = consumeToken();
1230 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001231 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001232 } else {
1233 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1234 << "exclude";
1235 }
1236 break;
1237 }
1238
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001239 case MMToken::PrivateKeyword: {
1240 SourceLocation PrivateLoc = consumeToken();
1241 if (Tok.is(MMToken::HeaderKeyword)) {
1242 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1243 } else {
1244 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1245 << "private";
1246 }
1247 break;
1248 }
1249
Douglas Gregor489ad432011-12-08 18:00:48 +00001250 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001251 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001252 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001253
1254 case MMToken::LinkKeyword:
1255 parseLinkDecl();
1256 break;
1257
Douglas Gregora30cfe52011-11-11 19:10:28 +00001258 default:
1259 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1260 consumeToken();
1261 break;
1262 }
1263 } while (!Done);
1264
1265 if (Tok.is(MMToken::RBrace))
1266 consumeToken();
1267 else {
1268 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1269 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1270 HadError = true;
1271 }
1272
Douglas Gregor8767dc22013-01-14 17:57:51 +00001273 // If the active module is a top-level framework, and there are no link
1274 // libraries, automatically link against the framework.
1275 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1276 ActiveModule->LinkLibraries.empty()) {
1277 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1278 }
1279
Douglas Gregor587986e2011-12-07 02:23:45 +00001280 // We're done parsing this module. Pop back to the previous module.
1281 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001282}
Douglas Gregord620a842011-12-06 17:16:41 +00001283
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001284/// \brief Parse an extern module declaration.
1285///
1286/// extern module-declaration:
1287/// 'extern' 'module' module-id string-literal
1288void ModuleMapParser::parseExternModuleDecl() {
1289 assert(Tok.is(MMToken::ExternKeyword));
1290 consumeToken(); // 'extern' keyword
1291
1292 // Parse 'module' keyword.
1293 if (!Tok.is(MMToken::ModuleKeyword)) {
1294 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1295 consumeToken();
1296 HadError = true;
1297 return;
1298 }
1299 consumeToken(); // 'module' keyword
1300
1301 // Parse the module name.
1302 ModuleId Id;
1303 if (parseModuleId(Id)) {
1304 HadError = true;
1305 return;
1306 }
1307
1308 // Parse the referenced module map file name.
1309 if (!Tok.is(MMToken::StringLiteral)) {
1310 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1311 HadError = true;
1312 return;
1313 }
1314 std::string FileName = Tok.getString();
1315 consumeToken(); // filename
1316
1317 StringRef FileNameRef = FileName;
1318 SmallString<128> ModuleMapFileName;
1319 if (llvm::sys::path::is_relative(FileNameRef)) {
1320 ModuleMapFileName += Directory->getName();
1321 llvm::sys::path::append(ModuleMapFileName, FileName);
1322 FileNameRef = ModuleMapFileName.str();
1323 }
1324 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1325 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1326}
1327
Douglas Gregor51f564f2011-12-31 04:05:44 +00001328/// \brief Parse a requires declaration.
1329///
1330/// requires-declaration:
1331/// 'requires' feature-list
1332///
1333/// feature-list:
1334/// identifier ',' feature-list
1335/// identifier
1336void ModuleMapParser::parseRequiresDecl() {
1337 assert(Tok.is(MMToken::RequiresKeyword));
1338
1339 // Parse 'requires' keyword.
1340 consumeToken();
1341
1342 // Parse the feature-list.
1343 do {
1344 if (!Tok.is(MMToken::Identifier)) {
1345 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1346 HadError = true;
1347 return;
1348 }
1349
1350 // Consume the feature name.
1351 std::string Feature = Tok.getString();
1352 consumeToken();
1353
1354 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001355 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001356
1357 if (!Tok.is(MMToken::Comma))
1358 break;
1359
1360 // Consume the comma.
1361 consumeToken();
1362 } while (true);
1363}
1364
Douglas Gregord620a842011-12-06 17:16:41 +00001365/// \brief Append to \p Paths the set of paths needed to get to the
1366/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001367static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001368 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001369 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001370 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001371 for (; Mod; Mod = Mod->Parent) {
1372 if (Mod->IsFramework)
1373 Paths.push_back(Mod->Name);
1374 }
1375
1376 if (Paths.empty())
1377 return;
1378
1379 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001380 for (unsigned I = Paths.size() - 1; I != 0; --I)
1381 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregord620a842011-12-06 17:16:41 +00001382}
1383
Douglas Gregora30cfe52011-11-11 19:10:28 +00001384/// \brief Parse a header declaration.
1385///
1386/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001387/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001388/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001389void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1390 SourceLocation LeadingLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001391 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001392 consumeToken();
1393
Douglas Gregora30cfe52011-11-11 19:10:28 +00001394 // Parse the header name.
1395 if (!Tok.is(MMToken::StringLiteral)) {
1396 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1397 << "header";
1398 HadError = true;
1399 return;
1400 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001401 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001402 SourceLocation FileNameLoc = consumeToken();
1403
Douglas Gregor77d029f2011-12-08 19:11:24 +00001404 // Check whether we already have an umbrella.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001405 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Douglas Gregor77d029f2011-12-08 19:11:24 +00001406 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1407 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001408 HadError = true;
1409 return;
1410 }
1411
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001412 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001413 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001414 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001415 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001416 if (llvm::sys::path::is_absolute(FileName)) {
1417 PathName = FileName;
1418 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001419 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1420 PathName = Dir->getName();
1421 llvm::sys::path::append(PathName, FileName);
1422 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001423 } else {
1424 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001425 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001426 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001427
Douglas Gregord620a842011-12-06 17:16:41 +00001428 if (ActiveModule->isPartOfFramework()) {
1429 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001430
1431 // Check whether this file is in the public headers.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001432 llvm::sys::path::append(PathName, "Headers", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001433 File = SourceMgr.getFileManager().getFile(PathName);
1434
1435 if (!File) {
1436 // Check whether this file is in the private headers.
1437 PathName.resize(PathLength);
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001438 llvm::sys::path::append(PathName, "PrivateHeaders", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001439 File = SourceMgr.getFileManager().getFile(PathName);
1440 }
1441 } else {
1442 // Lookup for normal headers.
1443 llvm::sys::path::append(PathName, FileName);
1444 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001445
1446 // If this is a system module with a top-level header, this header
1447 // may have a counterpart (or replacement) in the set of headers
1448 // supplied by Clang. Find that builtin header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001449 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1450 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1451 isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001452 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001453 llvm::sys::path::append(BuiltinPathName, FileName);
1454 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1455
1456 // If Clang supplies this header but the underlying system does not,
1457 // just silently swap in our builtin version. Otherwise, we'll end
1458 // up adding both (later).
1459 if (!File && BuiltinFile) {
1460 File = BuiltinFile;
1461 BuiltinFile = 0;
1462 }
1463 }
Douglas Gregord620a842011-12-06 17:16:41 +00001464 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001465 }
Douglas Gregora8654052011-11-17 22:09:43 +00001466
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001467 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1468 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001469 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001470 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001471 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001472 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001473 HadError = true;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001474 } else if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001475 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001476 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001477 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001478 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001479 HadError = true;
1480 } else {
1481 // Record this umbrella header.
1482 Map.setUmbrellaHeader(ActiveModule, File);
1483 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001484 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001485 // Record this header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001486 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1487 if (LeadingToken == MMToken::ExcludeKeyword)
1488 Role = ModuleMap::ExcludedHeader;
1489 else if (LeadingToken == MMToken::PrivateKeyword)
1490 Role = ModuleMap::PrivateHeader;
1491 else
1492 assert(LeadingToken == MMToken::HeaderKeyword);
1493
1494 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001495
1496 // If there is a builtin counterpart to this file, add it now.
1497 if (BuiltinFile)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001498 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001499 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001500 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor71f49f52012-11-15 19:47:16 +00001501 // Ignore excluded header files. They're optional anyway.
1502
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001503 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001504 << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001505 HadError = true;
1506 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001507}
1508
Douglas Gregor77d029f2011-12-08 19:11:24 +00001509/// \brief Parse an umbrella directory declaration.
1510///
1511/// umbrella-dir-declaration:
1512/// umbrella string-literal
1513void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1514 // Parse the directory name.
1515 if (!Tok.is(MMToken::StringLiteral)) {
1516 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1517 << "umbrella";
1518 HadError = true;
1519 return;
1520 }
1521
1522 std::string DirName = Tok.getString();
1523 SourceLocation DirNameLoc = consumeToken();
1524
1525 // Check whether we already have an umbrella.
1526 if (ActiveModule->Umbrella) {
1527 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1528 << ActiveModule->getFullModuleName();
1529 HadError = true;
1530 return;
1531 }
1532
1533 // Look for this file.
1534 const DirectoryEntry *Dir = 0;
1535 if (llvm::sys::path::is_absolute(DirName))
1536 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1537 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001538 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001539 PathName = Directory->getName();
1540 llvm::sys::path::append(PathName, DirName);
1541 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1542 }
1543
1544 if (!Dir) {
1545 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1546 << DirName;
1547 HadError = true;
1548 return;
1549 }
1550
1551 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1552 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1553 << OwningModule->getFullModuleName();
1554 HadError = true;
1555 return;
1556 }
1557
1558 // Record this umbrella directory.
1559 Map.setUmbrellaDir(ActiveModule, Dir);
1560}
1561
Douglas Gregor90db2602011-12-02 01:47:07 +00001562/// \brief Parse a module export declaration.
1563///
1564/// export-declaration:
1565/// 'export' wildcard-module-id
1566///
1567/// wildcard-module-id:
1568/// identifier
1569/// '*'
1570/// identifier '.' wildcard-module-id
1571void ModuleMapParser::parseExportDecl() {
1572 assert(Tok.is(MMToken::ExportKeyword));
1573 SourceLocation ExportLoc = consumeToken();
1574
1575 // Parse the module-id with an optional wildcard at the end.
1576 ModuleId ParsedModuleId;
1577 bool Wildcard = false;
1578 do {
1579 if (Tok.is(MMToken::Identifier)) {
1580 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1581 Tok.getLocation()));
1582 consumeToken();
1583
1584 if (Tok.is(MMToken::Period)) {
1585 consumeToken();
1586 continue;
1587 }
1588
1589 break;
1590 }
1591
1592 if(Tok.is(MMToken::Star)) {
1593 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001594 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001595 break;
1596 }
1597
1598 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1599 HadError = true;
1600 return;
1601 } while (true);
1602
1603 Module::UnresolvedExportDecl Unresolved = {
1604 ExportLoc, ParsedModuleId, Wildcard
1605 };
1606 ActiveModule->UnresolvedExports.push_back(Unresolved);
1607}
1608
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001609/// \brief Parse a link declaration.
1610///
1611/// module-declaration:
1612/// 'link' 'framework'[opt] string-literal
1613void ModuleMapParser::parseLinkDecl() {
1614 assert(Tok.is(MMToken::LinkKeyword));
1615 SourceLocation LinkLoc = consumeToken();
1616
1617 // Parse the optional 'framework' keyword.
1618 bool IsFramework = false;
1619 if (Tok.is(MMToken::FrameworkKeyword)) {
1620 consumeToken();
1621 IsFramework = true;
1622 }
1623
1624 // Parse the library name
1625 if (!Tok.is(MMToken::StringLiteral)) {
1626 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1627 << IsFramework << SourceRange(LinkLoc);
1628 HadError = true;
1629 return;
1630 }
1631
1632 std::string LibraryName = Tok.getString();
1633 consumeToken();
1634 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1635 IsFramework));
1636}
1637
Douglas Gregor63a72682013-03-20 00:22:05 +00001638/// \brief Parse a configuration macro declaration.
1639///
1640/// module-declaration:
1641/// 'config_macros' attributes[opt] config-macro-list?
1642///
1643/// config-macro-list:
1644/// identifier (',' identifier)?
1645void ModuleMapParser::parseConfigMacros() {
1646 assert(Tok.is(MMToken::ConfigMacros));
1647 SourceLocation ConfigMacrosLoc = consumeToken();
1648
1649 // Only top-level modules can have configuration macros.
1650 if (ActiveModule->Parent) {
1651 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1652 }
1653
1654 // Parse the optional attributes.
1655 Attributes Attrs;
1656 parseOptionalAttributes(Attrs);
1657 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1658 ActiveModule->ConfigMacrosExhaustive = true;
1659 }
1660
1661 // If we don't have an identifier, we're done.
1662 if (!Tok.is(MMToken::Identifier))
1663 return;
1664
1665 // Consume the first identifier.
1666 if (!ActiveModule->Parent) {
1667 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1668 }
1669 consumeToken();
1670
1671 do {
1672 // If there's a comma, consume it.
1673 if (!Tok.is(MMToken::Comma))
1674 break;
1675 consumeToken();
1676
1677 // We expect to see a macro name here.
1678 if (!Tok.is(MMToken::Identifier)) {
1679 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1680 break;
1681 }
1682
1683 // Consume the macro name.
1684 if (!ActiveModule->Parent) {
1685 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1686 }
1687 consumeToken();
1688 } while (true);
1689}
1690
Douglas Gregor906d66a2013-03-20 21:10:35 +00001691/// \brief Format a module-id into a string.
1692static std::string formatModuleId(const ModuleId &Id) {
1693 std::string result;
1694 {
1695 llvm::raw_string_ostream OS(result);
1696
1697 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1698 if (I)
1699 OS << ".";
1700 OS << Id[I].first;
1701 }
1702 }
1703
1704 return result;
1705}
1706
1707/// \brief Parse a conflict declaration.
1708///
1709/// module-declaration:
1710/// 'conflict' module-id ',' string-literal
1711void ModuleMapParser::parseConflict() {
1712 assert(Tok.is(MMToken::Conflict));
1713 SourceLocation ConflictLoc = consumeToken();
1714 Module::UnresolvedConflict Conflict;
1715
1716 // Parse the module-id.
1717 if (parseModuleId(Conflict.Id))
1718 return;
1719
1720 // Parse the ','.
1721 if (!Tok.is(MMToken::Comma)) {
1722 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1723 << SourceRange(ConflictLoc);
1724 return;
1725 }
1726 consumeToken();
1727
1728 // Parse the message.
1729 if (!Tok.is(MMToken::StringLiteral)) {
1730 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1731 << formatModuleId(Conflict.Id);
1732 return;
1733 }
1734 Conflict.Message = Tok.getString().str();
1735 consumeToken();
1736
1737 // Add this unresolved conflict.
1738 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1739}
1740
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001741/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001742///
1743/// module-declaration:
1744/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1745/// { inferred-module-member* }
1746///
1747/// inferred-module-member:
1748/// 'export' '*'
1749/// 'exclude' identifier
1750void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001751 assert(Tok.is(MMToken::Star));
1752 SourceLocation StarLoc = consumeToken();
1753 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001754
Douglas Gregor1e123682011-12-05 22:27:44 +00001755 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001756 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001757 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1758 Failed = true;
1759 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001760
1761 if (ActiveModule) {
1762 // Inferred modules must have umbrella directories.
1763 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1764 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1765 Failed = true;
1766 }
1767
1768 // Check for redefinition of an inferred module.
1769 if (!Failed && ActiveModule->InferSubmodules) {
1770 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1771 if (ActiveModule->InferredSubmoduleLoc.isValid())
1772 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1773 diag::note_mmap_prev_definition);
1774 Failed = true;
1775 }
1776
1777 // Check for the 'framework' keyword, which is not permitted here.
1778 if (Framework) {
1779 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1780 Framework = false;
1781 }
1782 } else if (Explicit) {
1783 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1784 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001785 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001786
Douglas Gregor1e123682011-12-05 22:27:44 +00001787 // If there were any problems with this inferred submodule, skip its body.
1788 if (Failed) {
1789 if (Tok.is(MMToken::LBrace)) {
1790 consumeToken();
1791 skipUntil(MMToken::RBrace);
1792 if (Tok.is(MMToken::RBrace))
1793 consumeToken();
1794 }
1795 HadError = true;
1796 return;
1797 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001798
1799 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001800 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001801 parseOptionalAttributes(Attrs);
1802
1803 if (ActiveModule) {
1804 // Note that we have an inferred submodule.
1805 ActiveModule->InferSubmodules = true;
1806 ActiveModule->InferredSubmoduleLoc = StarLoc;
1807 ActiveModule->InferExplicitSubmodules = Explicit;
1808 } else {
1809 // We'll be inferring framework modules for this directory.
1810 Map.InferredDirectories[Directory].InferModules = true;
1811 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1812 }
1813
Douglas Gregor1e123682011-12-05 22:27:44 +00001814 // Parse the opening brace.
1815 if (!Tok.is(MMToken::LBrace)) {
1816 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1817 HadError = true;
1818 return;
1819 }
1820 SourceLocation LBraceLoc = consumeToken();
1821
1822 // Parse the body of the inferred submodule.
1823 bool Done = false;
1824 do {
1825 switch (Tok.Kind) {
1826 case MMToken::EndOfFile:
1827 case MMToken::RBrace:
1828 Done = true;
1829 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001830
1831 case MMToken::ExcludeKeyword: {
1832 if (ActiveModule) {
1833 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001834 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001835 consumeToken();
1836 break;
1837 }
1838
1839 consumeToken();
1840 if (!Tok.is(MMToken::Identifier)) {
1841 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1842 break;
1843 }
1844
1845 Map.InferredDirectories[Directory].ExcludedModules
1846 .push_back(Tok.getString());
1847 consumeToken();
1848 break;
1849 }
1850
1851 case MMToken::ExportKeyword:
1852 if (!ActiveModule) {
1853 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001854 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001855 consumeToken();
1856 break;
1857 }
1858
Douglas Gregor1e123682011-12-05 22:27:44 +00001859 consumeToken();
1860 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001861 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001862 else
1863 Diags.Report(Tok.getLocation(),
1864 diag::err_mmap_expected_export_wildcard);
1865 consumeToken();
1866 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001867
Douglas Gregor1e123682011-12-05 22:27:44 +00001868 case MMToken::ExplicitKeyword:
1869 case MMToken::ModuleKeyword:
1870 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001871 case MMToken::PrivateKeyword:
Douglas Gregor1e123682011-12-05 22:27:44 +00001872 case MMToken::UmbrellaKeyword:
1873 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001874 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001875 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001876 consumeToken();
1877 break;
1878 }
1879 } while (!Done);
1880
1881 if (Tok.is(MMToken::RBrace))
1882 consumeToken();
1883 else {
1884 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1885 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1886 HadError = true;
1887 }
1888}
1889
Douglas Gregor82e52372012-11-06 19:39:40 +00001890/// \brief Parse optional attributes.
1891///
1892/// attributes:
1893/// attribute attributes
1894/// attribute
1895///
1896/// attribute:
1897/// [ identifier ]
1898///
1899/// \param Attrs Will be filled in with the parsed attributes.
1900///
1901/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001902bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001903 bool HadError = false;
1904
1905 while (Tok.is(MMToken::LSquare)) {
1906 // Consume the '['.
1907 SourceLocation LSquareLoc = consumeToken();
1908
1909 // Check whether we have an attribute name here.
1910 if (!Tok.is(MMToken::Identifier)) {
1911 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1912 skipUntil(MMToken::RSquare);
1913 if (Tok.is(MMToken::RSquare))
1914 consumeToken();
1915 HadError = true;
1916 }
1917
1918 // Decode the attribute name.
1919 AttributeKind Attribute
1920 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001921 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00001922 .Case("system", AT_system)
1923 .Default(AT_unknown);
1924 switch (Attribute) {
1925 case AT_unknown:
1926 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1927 << Tok.getString();
1928 break;
1929
1930 case AT_system:
1931 Attrs.IsSystem = true;
1932 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001933
1934 case AT_exhaustive:
1935 Attrs.IsExhaustive = true;
1936 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001937 }
1938 consumeToken();
1939
1940 // Consume the ']'.
1941 if (!Tok.is(MMToken::RSquare)) {
1942 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1943 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1944 skipUntil(MMToken::RSquare);
1945 HadError = true;
1946 }
1947
1948 if (Tok.is(MMToken::RSquare))
1949 consumeToken();
1950 }
1951
1952 return HadError;
1953}
1954
Douglas Gregor6a1db482011-12-09 02:04:43 +00001955/// \brief If there is a specific header search directory due the presence
1956/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1957const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1958 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1959 // If we have an umbrella directory, use that.
1960 if (Mod->hasUmbrellaDir())
1961 return Mod->getUmbrellaDir();
1962
1963 // If we have a framework directory, stop looking.
1964 if (Mod->IsFramework)
1965 return 0;
1966 }
1967
1968 return 0;
1969}
1970
Douglas Gregora30cfe52011-11-11 19:10:28 +00001971/// \brief Parse a module map file.
1972///
1973/// module-map-file:
1974/// module-declaration*
1975bool ModuleMapParser::parseModuleMapFile() {
1976 do {
1977 switch (Tok.Kind) {
1978 case MMToken::EndOfFile:
1979 return HadError;
1980
Douglas Gregor587986e2011-12-07 02:23:45 +00001981 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001982 case MMToken::ExternKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001983 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001984 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001985 parseModuleDecl();
1986 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001987
Douglas Gregor51f564f2011-12-31 04:05:44 +00001988 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00001989 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00001990 case MMToken::Conflict:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001991 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001992 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001993 case MMToken::HeaderKeyword:
1994 case MMToken::Identifier:
1995 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001996 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001997 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001998 case MMToken::Period:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001999 case MMToken::PrivateKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002000 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00002001 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00002002 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00002003 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002004 case MMToken::StringLiteral:
2005 case MMToken::UmbrellaKeyword:
2006 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2007 HadError = true;
2008 consumeToken();
2009 break;
2010 }
2011 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002012}
2013
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002014bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor7005b902013-01-10 01:43:00 +00002015 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2016 = ParsedModuleMap.find(File);
2017 if (Known != ParsedModuleMap.end())
2018 return Known->second;
2019
Douglas Gregordc58aa72012-01-30 06:01:29 +00002020 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00002021 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
2022 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
2023 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00002024 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00002025
2026 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00002027 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
2028 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00002029 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002030 BuiltinIncludeDir, IsSystem);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002031 bool Result = Parser.parseModuleMapFile();
2032 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00002033 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00002034 return Result;
2035}