blob: df80a93e4db84d66df2d346feae96836900eb4d4 [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");
Benjamin Kramer0f599ac2013-09-11 11:23:15 +0000544 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000545 for (llvm::sys::fs::directory_iterator
Benjamin Kramer0f599ac2013-09-11 11:23:15 +0000546 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000547 Dir != DirEnd && !EC; Dir.increment(EC)) {
548 if (!StringRef(Dir->path()).endswith(".framework"))
549 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000550
Douglas Gregorac252a32011-12-06 19:39:29 +0000551 if (const DirectoryEntry *SubframeworkDir
552 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000553 // Note: as an egregious but useful hack, we use the real path here and
554 // check whether it is actually a subdirectory of the parent directory.
555 // This will not be the case if the 'subframework' is actually a symlink
556 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000557 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
558 bool FoundParent = false;
559 do {
560 // Get the parent directory name.
561 SubframeworkDirName
562 = llvm::sys::path::parent_path(SubframeworkDirName);
563 if (SubframeworkDirName.empty())
564 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000565
Douglas Gregor713b7c02013-01-26 00:55:12 +0000566 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
567 FoundParent = true;
568 break;
569 }
570 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000571
Douglas Gregor713b7c02013-01-26 00:55:12 +0000572 if (!FoundParent)
573 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000574
Douglas Gregorac252a32011-12-06 19:39:29 +0000575 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000576 SmallString<32> NameBuf;
577 inferFrameworkModule(sanitizeFilenameAsIdentifier(
578 llvm::sys::path::stem(Dir->path()), NameBuf),
579 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000580 }
581 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000582
Douglas Gregor8767dc22013-01-14 17:57:51 +0000583 // If the module is a top-level framework, automatically link against the
584 // framework.
585 if (!Result->isSubFramework()) {
586 inferFrameworkLink(Result, FrameworkDir, FileMgr);
587 }
588
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000589 return Result;
590}
591
Douglas Gregore209e502011-12-06 01:10:29 +0000592void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000593 Headers[UmbrellaHeader] = KnownHeader(Mod, NormalHeader);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000594 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000595 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000596}
597
Douglas Gregor77d029f2011-12-08 19:11:24 +0000598void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
599 Mod->Umbrella = UmbrellaDir;
600 UmbrellaDirs[UmbrellaDir] = Mod;
601}
602
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000603void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000604 ModuleHeaderRole Role) {
605 if (Role == ExcludedHeader) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000606 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000607 } else {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000608 if (Role == PrivateHeader)
609 Mod->PrivateHeaders.push_back(Header);
610 else
611 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000612 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000613 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000614 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000615 Headers[Header] = KnownHeader(Mod, Role);
Douglas Gregore209e502011-12-06 01:10:29 +0000616}
617
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000618const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000619ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000620 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
621 return 0;
622
623 return SourceMgr->getFileEntryForID(
624 SourceMgr->getFileID(Module->DefinitionLoc));
625}
626
Douglas Gregora30cfe52011-11-11 19:10:28 +0000627void ModuleMap::dump() {
628 llvm::errs() << "Modules:";
629 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
630 MEnd = Modules.end();
631 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000632 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000633
634 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000635 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000636 H != HEnd; ++H) {
637 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000638 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000639 }
640}
641
Douglas Gregor90db2602011-12-02 01:47:07 +0000642bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
643 bool HadError = false;
644 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
645 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
646 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000647 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000648 Mod->Exports.push_back(Export);
649 else
650 HadError = true;
651 }
652 Mod->UnresolvedExports.clear();
653 return HadError;
654}
655
Douglas Gregor906d66a2013-03-20 21:10:35 +0000656bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
657 bool HadError = false;
658 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
659 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
660 Mod, Complain);
661 if (!OtherMod) {
662 HadError = true;
663 continue;
664 }
665
666 Module::Conflict Conflict;
667 Conflict.Other = OtherMod;
668 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
669 Mod->Conflicts.push_back(Conflict);
670 }
671 Mod->UnresolvedConflicts.clear();
672 return HadError;
673}
674
Douglas Gregor55988682011-12-05 16:33:54 +0000675Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
676 if (Loc.isInvalid())
677 return 0;
678
679 // Use the expansion location to determine which module we're in.
680 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
681 if (!ExpansionLoc.isFileID())
682 return 0;
683
684
685 const SourceManager &SrcMgr = Loc.getManager();
686 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000687
Douglas Gregor303aae92012-01-06 17:19:32 +0000688 while (const FileEntry *ExpansionFile
689 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
690 // Find the module that owns this header (if any).
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000691 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor303aae92012-01-06 17:19:32 +0000692 return Mod;
693
694 // No module owns this header, so look up the inclusion chain to see if
695 // any included header has an associated module.
696 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
697 if (IncludeLoc.isInvalid())
698 return 0;
699
700 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
701 }
702
703 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000704}
705
Douglas Gregora30cfe52011-11-11 19:10:28 +0000706//----------------------------------------------------------------------------//
707// Module map file parser
708//----------------------------------------------------------------------------//
709
710namespace clang {
711 /// \brief A token in a module map file.
712 struct MMToken {
713 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000714 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000715 ConfigMacros,
Douglas Gregor906d66a2013-03-20 21:10:35 +0000716 Conflict,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000717 EndOfFile,
718 HeaderKeyword,
719 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000720 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000721 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000722 ExportKeyword,
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000723 ExternKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000724 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000725 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000726 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000727 Period,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000728 PrivateKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000729 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000730 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000731 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000732 StringLiteral,
733 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000734 RBrace,
735 LSquare,
736 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000737 } Kind;
738
739 unsigned Location;
740 unsigned StringLength;
741 const char *StringData;
742
743 void clear() {
744 Kind = EndOfFile;
745 Location = 0;
746 StringLength = 0;
747 StringData = 0;
748 }
749
750 bool is(TokenKind K) const { return Kind == K; }
751
752 SourceLocation getLocation() const {
753 return SourceLocation::getFromRawEncoding(Location);
754 }
755
756 StringRef getString() const {
757 return StringRef(StringData, StringLength);
758 }
759 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000760
761 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000762 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000763 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000764
765 /// \brief Whether this is a system module.
766 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000767
768 /// \brief Whether this is an exhaustive set of configuration macros.
769 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000770 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000771
Douglas Gregor82e52372012-11-06 19:39:40 +0000772
Douglas Gregora30cfe52011-11-11 19:10:28 +0000773 class ModuleMapParser {
774 Lexer &L;
775 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000776
777 /// \brief Default target information, used only for string literal
778 /// parsing.
779 const TargetInfo *Target;
780
Douglas Gregora30cfe52011-11-11 19:10:28 +0000781 DiagnosticsEngine &Diags;
782 ModuleMap &Map;
783
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000784 /// \brief The directory that this module map resides in.
785 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000786
787 /// \brief The directory containing Clang-supplied headers.
788 const DirectoryEntry *BuiltinIncludeDir;
789
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000790 /// \brief Whether this module map is in a system header directory.
791 bool IsSystem;
792
Douglas Gregora30cfe52011-11-11 19:10:28 +0000793 /// \brief Whether an error occurred.
794 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000795
Douglas Gregora30cfe52011-11-11 19:10:28 +0000796 /// \brief Stores string data for the various string literals referenced
797 /// during parsing.
798 llvm::BumpPtrAllocator StringData;
799
800 /// \brief The current token.
801 MMToken Tok;
802
803 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000804 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000805
806 /// \brief Consume the current token and return its location.
807 SourceLocation consumeToken();
808
809 /// \brief Skip tokens until we reach the a token with the given kind
810 /// (or the end of the file).
811 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000812
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000813 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000814 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000815 void parseModuleDecl();
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000816 void parseExternModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000817 void parseRequiresDecl();
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000818 void parseHeaderDecl(clang::MMToken::TokenKind,
819 SourceLocation LeadingLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000820 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000821 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000822 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000823 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000824 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000825 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000826 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000827
Douglas Gregor6a1db482011-12-09 02:04:43 +0000828 const DirectoryEntry *getOverriddenHeaderSearchDir();
829
Douglas Gregora30cfe52011-11-11 19:10:28 +0000830 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000831 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000832 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000833 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000834 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000835 const DirectoryEntry *Directory,
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000836 const DirectoryEntry *BuiltinIncludeDir,
837 bool IsSystem)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000838 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000839 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
840 IsSystem(IsSystem), HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000841 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000842 Tok.clear();
843 consumeToken();
844 }
845
846 bool parseModuleMapFile();
847 };
848}
849
850SourceLocation ModuleMapParser::consumeToken() {
851retry:
852 SourceLocation Result = Tok.getLocation();
853 Tok.clear();
854
855 Token LToken;
856 L.LexFromRawLexer(LToken);
857 Tok.Location = LToken.getLocation().getRawEncoding();
858 switch (LToken.getKind()) {
859 case tok::raw_identifier:
860 Tok.StringData = LToken.getRawIdentifierData();
861 Tok.StringLength = LToken.getLength();
862 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000863 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000864 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000865 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000866 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000867 .Case("export", MMToken::ExportKeyword)
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000868 .Case("extern", MMToken::ExternKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000869 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000870 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000871 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000872 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000873 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000874 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000875 .Case("umbrella", MMToken::UmbrellaKeyword)
876 .Default(MMToken::Identifier);
877 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000878
879 case tok::comma:
880 Tok.Kind = MMToken::Comma;
881 break;
882
Douglas Gregora30cfe52011-11-11 19:10:28 +0000883 case tok::eof:
884 Tok.Kind = MMToken::EndOfFile;
885 break;
886
887 case tok::l_brace:
888 Tok.Kind = MMToken::LBrace;
889 break;
890
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000891 case tok::l_square:
892 Tok.Kind = MMToken::LSquare;
893 break;
894
Douglas Gregor90db2602011-12-02 01:47:07 +0000895 case tok::period:
896 Tok.Kind = MMToken::Period;
897 break;
898
Douglas Gregora30cfe52011-11-11 19:10:28 +0000899 case tok::r_brace:
900 Tok.Kind = MMToken::RBrace;
901 break;
902
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000903 case tok::r_square:
904 Tok.Kind = MMToken::RSquare;
905 break;
906
Douglas Gregor90db2602011-12-02 01:47:07 +0000907 case tok::star:
908 Tok.Kind = MMToken::Star;
909 break;
910
Douglas Gregora30cfe52011-11-11 19:10:28 +0000911 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000912 if (LToken.hasUDSuffix()) {
913 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
914 HadError = true;
915 goto retry;
916 }
917
Douglas Gregora30cfe52011-11-11 19:10:28 +0000918 // Parse the string literal.
919 LangOptions LangOpts;
920 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
921 if (StringLiteral.hadError)
922 goto retry;
923
924 // Copy the string literal into our string data allocator.
925 unsigned Length = StringLiteral.GetStringLength();
926 char *Saved = StringData.Allocate<char>(Length + 1);
927 memcpy(Saved, StringLiteral.GetString().data(), Length);
928 Saved[Length] = 0;
929
930 // Form the token.
931 Tok.Kind = MMToken::StringLiteral;
932 Tok.StringData = Saved;
933 Tok.StringLength = Length;
934 break;
935 }
936
937 case tok::comment:
938 goto retry;
939
940 default:
941 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
942 HadError = true;
943 goto retry;
944 }
945
946 return Result;
947}
948
949void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
950 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000951 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000952 do {
953 switch (Tok.Kind) {
954 case MMToken::EndOfFile:
955 return;
956
957 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000958 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000959 return;
960
961 ++braceDepth;
962 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000963
964 case MMToken::LSquare:
965 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
966 return;
967
968 ++squareDepth;
969 break;
970
Douglas Gregora30cfe52011-11-11 19:10:28 +0000971 case MMToken::RBrace:
972 if (braceDepth > 0)
973 --braceDepth;
974 else if (Tok.is(K))
975 return;
976 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000977
978 case MMToken::RSquare:
979 if (squareDepth > 0)
980 --squareDepth;
981 else if (Tok.is(K))
982 return;
983 break;
984
Douglas Gregora30cfe52011-11-11 19:10:28 +0000985 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000986 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000987 return;
988 break;
989 }
990
991 consumeToken();
992 } while (true);
993}
994
Douglas Gregor587986e2011-12-07 02:23:45 +0000995/// \brief Parse a module-id.
996///
997/// module-id:
998/// identifier
999/// identifier '.' module-id
1000///
1001/// \returns true if an error occurred, false otherwise.
1002bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1003 Id.clear();
1004 do {
1005 if (Tok.is(MMToken::Identifier)) {
1006 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1007 consumeToken();
1008 } else {
1009 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1010 return true;
1011 }
1012
1013 if (!Tok.is(MMToken::Period))
1014 break;
1015
1016 consumeToken();
1017 } while (true);
1018
1019 return false;
1020}
1021
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001022namespace {
1023 /// \brief Enumerates the known attributes.
1024 enum AttributeKind {
1025 /// \brief An unknown attribute.
1026 AT_unknown,
1027 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001028 AT_system,
1029 /// \brief The 'exhaustive' attribute.
1030 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001031 };
1032}
1033
Douglas Gregora30cfe52011-11-11 19:10:28 +00001034/// \brief Parse a module declaration.
1035///
1036/// module-declaration:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001037/// 'extern' 'module' module-id string-literal
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001038/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1039/// { module-member* }
1040///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001041/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001042/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001043/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001044/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001045/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001046/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001047///
1048/// submodule-declaration:
1049/// module-declaration
1050/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001051void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001052 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001053 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1054 if (Tok.is(MMToken::ExternKeyword)) {
1055 parseExternModuleDecl();
1056 return;
1057 }
1058
Douglas Gregord620a842011-12-06 17:16:41 +00001059 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001060 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001061 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001062 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001063
Douglas Gregord620a842011-12-06 17:16:41 +00001064 // Parse 'explicit' keyword, if present.
1065 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001066 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001067 Explicit = true;
1068 }
1069
1070 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001071 if (Tok.is(MMToken::FrameworkKeyword)) {
1072 consumeToken();
1073 Framework = true;
1074 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001075
1076 // Parse 'module' keyword.
1077 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001078 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001079 consumeToken();
1080 HadError = true;
1081 return;
1082 }
1083 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001084
1085 // If we have a wildcard for the module name, this is an inferred submodule.
1086 // Parse it.
1087 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001088 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001089
1090 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001091 ModuleId Id;
1092 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001093 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001094 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001095 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001096
Douglas Gregor587986e2011-12-07 02:23:45 +00001097 if (ActiveModule) {
1098 if (Id.size() > 1) {
1099 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1100 << SourceRange(Id.front().second, Id.back().second);
1101
1102 HadError = true;
1103 return;
1104 }
1105 } else if (Id.size() == 1 && Explicit) {
1106 // Top-level modules can't be explicit.
1107 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1108 Explicit = false;
1109 ExplicitLoc = SourceLocation();
1110 HadError = true;
1111 }
1112
1113 Module *PreviousActiveModule = ActiveModule;
1114 if (Id.size() > 1) {
1115 // This module map defines a submodule. Go find the module of which it
1116 // is a submodule.
1117 ActiveModule = 0;
1118 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1119 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1120 ActiveModule = Next;
1121 continue;
1122 }
1123
1124 if (ActiveModule) {
1125 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1126 << Id[I].first << ActiveModule->getTopLevelModule();
1127 } else {
1128 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1129 }
1130 HadError = true;
1131 return;
1132 }
1133 }
1134
1135 StringRef ModuleName = Id.back().first;
1136 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001137
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001138 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001139 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001140 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001141
Douglas Gregora30cfe52011-11-11 19:10:28 +00001142 // Parse the opening brace.
1143 if (!Tok.is(MMToken::LBrace)) {
1144 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1145 << ModuleName;
1146 HadError = true;
1147 return;
1148 }
1149 SourceLocation LBraceLoc = consumeToken();
1150
1151 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001152 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001153 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1154 // Skip the module definition.
1155 skipUntil(MMToken::RBrace);
1156 if (Tok.is(MMToken::RBrace))
1157 consumeToken();
1158 else {
1159 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1160 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1161 HadError = true;
1162 }
1163 return;
1164 }
1165
Douglas Gregora30cfe52011-11-11 19:10:28 +00001166 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1167 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001168 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001169
1170 // Skip the module definition.
1171 skipUntil(MMToken::RBrace);
1172 if (Tok.is(MMToken::RBrace))
1173 consumeToken();
1174
1175 HadError = true;
1176 return;
1177 }
1178
1179 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001180 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1181 Explicit).first;
1182 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001183 if (Attrs.IsSystem || IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001184 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001185
1186 bool Done = false;
1187 do {
1188 switch (Tok.Kind) {
1189 case MMToken::EndOfFile:
1190 case MMToken::RBrace:
1191 Done = true;
1192 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001193
1194 case MMToken::ConfigMacros:
1195 parseConfigMacros();
1196 break;
1197
Douglas Gregor906d66a2013-03-20 21:10:35 +00001198 case MMToken::Conflict:
1199 parseConflict();
1200 break;
1201
Douglas Gregora30cfe52011-11-11 19:10:28 +00001202 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001203 case MMToken::ExternKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001204 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001205 case MMToken::ModuleKeyword:
1206 parseModuleDecl();
1207 break;
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001208
Douglas Gregor90db2602011-12-02 01:47:07 +00001209 case MMToken::ExportKeyword:
1210 parseExportDecl();
1211 break;
1212
Douglas Gregor51f564f2011-12-31 04:05:44 +00001213 case MMToken::RequiresKeyword:
1214 parseRequiresDecl();
1215 break;
1216
Douglas Gregor77d029f2011-12-08 19:11:24 +00001217 case MMToken::UmbrellaKeyword: {
1218 SourceLocation UmbrellaLoc = consumeToken();
1219 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001220 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +00001221 else
1222 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001223 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001224 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001225
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001226 case MMToken::ExcludeKeyword: {
1227 SourceLocation ExcludeLoc = consumeToken();
1228 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001229 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001230 } else {
1231 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1232 << "exclude";
1233 }
1234 break;
1235 }
1236
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001237 case MMToken::PrivateKeyword: {
1238 SourceLocation PrivateLoc = consumeToken();
1239 if (Tok.is(MMToken::HeaderKeyword)) {
1240 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1241 } else {
1242 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1243 << "private";
1244 }
1245 break;
1246 }
1247
Douglas Gregor489ad432011-12-08 18:00:48 +00001248 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001249 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001250 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001251
1252 case MMToken::LinkKeyword:
1253 parseLinkDecl();
1254 break;
1255
Douglas Gregora30cfe52011-11-11 19:10:28 +00001256 default:
1257 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1258 consumeToken();
1259 break;
1260 }
1261 } while (!Done);
1262
1263 if (Tok.is(MMToken::RBrace))
1264 consumeToken();
1265 else {
1266 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1267 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1268 HadError = true;
1269 }
1270
Douglas Gregor8767dc22013-01-14 17:57:51 +00001271 // If the active module is a top-level framework, and there are no link
1272 // libraries, automatically link against the framework.
1273 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1274 ActiveModule->LinkLibraries.empty()) {
1275 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1276 }
1277
Douglas Gregor587986e2011-12-07 02:23:45 +00001278 // We're done parsing this module. Pop back to the previous module.
1279 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001280}
Douglas Gregord620a842011-12-06 17:16:41 +00001281
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001282/// \brief Parse an extern module declaration.
1283///
1284/// extern module-declaration:
1285/// 'extern' 'module' module-id string-literal
1286void ModuleMapParser::parseExternModuleDecl() {
1287 assert(Tok.is(MMToken::ExternKeyword));
1288 consumeToken(); // 'extern' keyword
1289
1290 // Parse 'module' keyword.
1291 if (!Tok.is(MMToken::ModuleKeyword)) {
1292 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1293 consumeToken();
1294 HadError = true;
1295 return;
1296 }
1297 consumeToken(); // 'module' keyword
1298
1299 // Parse the module name.
1300 ModuleId Id;
1301 if (parseModuleId(Id)) {
1302 HadError = true;
1303 return;
1304 }
1305
1306 // Parse the referenced module map file name.
1307 if (!Tok.is(MMToken::StringLiteral)) {
1308 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1309 HadError = true;
1310 return;
1311 }
1312 std::string FileName = Tok.getString();
1313 consumeToken(); // filename
1314
1315 StringRef FileNameRef = FileName;
1316 SmallString<128> ModuleMapFileName;
1317 if (llvm::sys::path::is_relative(FileNameRef)) {
1318 ModuleMapFileName += Directory->getName();
1319 llvm::sys::path::append(ModuleMapFileName, FileName);
1320 FileNameRef = ModuleMapFileName.str();
1321 }
1322 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1323 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1324}
1325
Douglas Gregor51f564f2011-12-31 04:05:44 +00001326/// \brief Parse a requires declaration.
1327///
1328/// requires-declaration:
1329/// 'requires' feature-list
1330///
1331/// feature-list:
1332/// identifier ',' feature-list
1333/// identifier
1334void ModuleMapParser::parseRequiresDecl() {
1335 assert(Tok.is(MMToken::RequiresKeyword));
1336
1337 // Parse 'requires' keyword.
1338 consumeToken();
1339
1340 // Parse the feature-list.
1341 do {
1342 if (!Tok.is(MMToken::Identifier)) {
1343 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1344 HadError = true;
1345 return;
1346 }
1347
1348 // Consume the feature name.
1349 std::string Feature = Tok.getString();
1350 consumeToken();
1351
1352 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001353 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001354
1355 if (!Tok.is(MMToken::Comma))
1356 break;
1357
1358 // Consume the comma.
1359 consumeToken();
1360 } while (true);
1361}
1362
Douglas Gregord620a842011-12-06 17:16:41 +00001363/// \brief Append to \p Paths the set of paths needed to get to the
1364/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001365static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001366 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001367 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001368 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001369 for (; Mod; Mod = Mod->Parent) {
1370 if (Mod->IsFramework)
1371 Paths.push_back(Mod->Name);
1372 }
1373
1374 if (Paths.empty())
1375 return;
1376
1377 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001378 for (unsigned I = Paths.size() - 1; I != 0; --I)
1379 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregord620a842011-12-06 17:16:41 +00001380}
1381
Douglas Gregora30cfe52011-11-11 19:10:28 +00001382/// \brief Parse a header declaration.
1383///
1384/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001385/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001386/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001387void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1388 SourceLocation LeadingLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001389 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001390 consumeToken();
1391
Douglas Gregora30cfe52011-11-11 19:10:28 +00001392 // Parse the header name.
1393 if (!Tok.is(MMToken::StringLiteral)) {
1394 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1395 << "header";
1396 HadError = true;
1397 return;
1398 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001399 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001400 SourceLocation FileNameLoc = consumeToken();
1401
Douglas Gregor77d029f2011-12-08 19:11:24 +00001402 // Check whether we already have an umbrella.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001403 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Douglas Gregor77d029f2011-12-08 19:11:24 +00001404 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1405 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001406 HadError = true;
1407 return;
1408 }
1409
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001410 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001411 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001412 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001413 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001414 if (llvm::sys::path::is_absolute(FileName)) {
1415 PathName = FileName;
1416 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001417 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1418 PathName = Dir->getName();
1419 llvm::sys::path::append(PathName, FileName);
1420 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001421 } else {
1422 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001423 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001424 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001425
Douglas Gregord620a842011-12-06 17:16:41 +00001426 if (ActiveModule->isPartOfFramework()) {
1427 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001428
1429 // Check whether this file is in the public headers.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001430 llvm::sys::path::append(PathName, "Headers", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001431 File = SourceMgr.getFileManager().getFile(PathName);
1432
1433 if (!File) {
1434 // Check whether this file is in the private headers.
1435 PathName.resize(PathLength);
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001436 llvm::sys::path::append(PathName, "PrivateHeaders", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001437 File = SourceMgr.getFileManager().getFile(PathName);
1438 }
1439 } else {
1440 // Lookup for normal headers.
1441 llvm::sys::path::append(PathName, FileName);
1442 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001443
1444 // If this is a system module with a top-level header, this header
1445 // may have a counterpart (or replacement) in the set of headers
1446 // supplied by Clang. Find that builtin header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001447 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1448 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1449 isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001450 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001451 llvm::sys::path::append(BuiltinPathName, FileName);
1452 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1453
1454 // If Clang supplies this header but the underlying system does not,
1455 // just silently swap in our builtin version. Otherwise, we'll end
1456 // up adding both (later).
1457 if (!File && BuiltinFile) {
1458 File = BuiltinFile;
1459 BuiltinFile = 0;
1460 }
1461 }
Douglas Gregord620a842011-12-06 17:16:41 +00001462 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001463 }
Douglas Gregora8654052011-11-17 22:09:43 +00001464
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001465 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1466 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001467 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001468 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001469 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001470 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001471 HadError = true;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001472 } else if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001473 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001474 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001475 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001476 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001477 HadError = true;
1478 } else {
1479 // Record this umbrella header.
1480 Map.setUmbrellaHeader(ActiveModule, File);
1481 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001482 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001483 // Record this header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001484 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1485 if (LeadingToken == MMToken::ExcludeKeyword)
1486 Role = ModuleMap::ExcludedHeader;
1487 else if (LeadingToken == MMToken::PrivateKeyword)
1488 Role = ModuleMap::PrivateHeader;
1489 else
1490 assert(LeadingToken == MMToken::HeaderKeyword);
1491
1492 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001493
1494 // If there is a builtin counterpart to this file, add it now.
1495 if (BuiltinFile)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001496 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001497 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001498 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor71f49f52012-11-15 19:47:16 +00001499 // Ignore excluded header files. They're optional anyway.
1500
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001501 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001502 << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001503 HadError = true;
1504 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001505}
1506
Douglas Gregor77d029f2011-12-08 19:11:24 +00001507/// \brief Parse an umbrella directory declaration.
1508///
1509/// umbrella-dir-declaration:
1510/// umbrella string-literal
1511void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1512 // Parse the directory name.
1513 if (!Tok.is(MMToken::StringLiteral)) {
1514 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1515 << "umbrella";
1516 HadError = true;
1517 return;
1518 }
1519
1520 std::string DirName = Tok.getString();
1521 SourceLocation DirNameLoc = consumeToken();
1522
1523 // Check whether we already have an umbrella.
1524 if (ActiveModule->Umbrella) {
1525 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1526 << ActiveModule->getFullModuleName();
1527 HadError = true;
1528 return;
1529 }
1530
1531 // Look for this file.
1532 const DirectoryEntry *Dir = 0;
1533 if (llvm::sys::path::is_absolute(DirName))
1534 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1535 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001536 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001537 PathName = Directory->getName();
1538 llvm::sys::path::append(PathName, DirName);
1539 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1540 }
1541
1542 if (!Dir) {
1543 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1544 << DirName;
1545 HadError = true;
1546 return;
1547 }
1548
1549 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1550 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1551 << OwningModule->getFullModuleName();
1552 HadError = true;
1553 return;
1554 }
1555
1556 // Record this umbrella directory.
1557 Map.setUmbrellaDir(ActiveModule, Dir);
1558}
1559
Douglas Gregor90db2602011-12-02 01:47:07 +00001560/// \brief Parse a module export declaration.
1561///
1562/// export-declaration:
1563/// 'export' wildcard-module-id
1564///
1565/// wildcard-module-id:
1566/// identifier
1567/// '*'
1568/// identifier '.' wildcard-module-id
1569void ModuleMapParser::parseExportDecl() {
1570 assert(Tok.is(MMToken::ExportKeyword));
1571 SourceLocation ExportLoc = consumeToken();
1572
1573 // Parse the module-id with an optional wildcard at the end.
1574 ModuleId ParsedModuleId;
1575 bool Wildcard = false;
1576 do {
1577 if (Tok.is(MMToken::Identifier)) {
1578 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1579 Tok.getLocation()));
1580 consumeToken();
1581
1582 if (Tok.is(MMToken::Period)) {
1583 consumeToken();
1584 continue;
1585 }
1586
1587 break;
1588 }
1589
1590 if(Tok.is(MMToken::Star)) {
1591 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001592 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001593 break;
1594 }
1595
1596 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1597 HadError = true;
1598 return;
1599 } while (true);
1600
1601 Module::UnresolvedExportDecl Unresolved = {
1602 ExportLoc, ParsedModuleId, Wildcard
1603 };
1604 ActiveModule->UnresolvedExports.push_back(Unresolved);
1605}
1606
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001607/// \brief Parse a link declaration.
1608///
1609/// module-declaration:
1610/// 'link' 'framework'[opt] string-literal
1611void ModuleMapParser::parseLinkDecl() {
1612 assert(Tok.is(MMToken::LinkKeyword));
1613 SourceLocation LinkLoc = consumeToken();
1614
1615 // Parse the optional 'framework' keyword.
1616 bool IsFramework = false;
1617 if (Tok.is(MMToken::FrameworkKeyword)) {
1618 consumeToken();
1619 IsFramework = true;
1620 }
1621
1622 // Parse the library name
1623 if (!Tok.is(MMToken::StringLiteral)) {
1624 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1625 << IsFramework << SourceRange(LinkLoc);
1626 HadError = true;
1627 return;
1628 }
1629
1630 std::string LibraryName = Tok.getString();
1631 consumeToken();
1632 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1633 IsFramework));
1634}
1635
Douglas Gregor63a72682013-03-20 00:22:05 +00001636/// \brief Parse a configuration macro declaration.
1637///
1638/// module-declaration:
1639/// 'config_macros' attributes[opt] config-macro-list?
1640///
1641/// config-macro-list:
1642/// identifier (',' identifier)?
1643void ModuleMapParser::parseConfigMacros() {
1644 assert(Tok.is(MMToken::ConfigMacros));
1645 SourceLocation ConfigMacrosLoc = consumeToken();
1646
1647 // Only top-level modules can have configuration macros.
1648 if (ActiveModule->Parent) {
1649 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1650 }
1651
1652 // Parse the optional attributes.
1653 Attributes Attrs;
1654 parseOptionalAttributes(Attrs);
1655 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1656 ActiveModule->ConfigMacrosExhaustive = true;
1657 }
1658
1659 // If we don't have an identifier, we're done.
1660 if (!Tok.is(MMToken::Identifier))
1661 return;
1662
1663 // Consume the first identifier.
1664 if (!ActiveModule->Parent) {
1665 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1666 }
1667 consumeToken();
1668
1669 do {
1670 // If there's a comma, consume it.
1671 if (!Tok.is(MMToken::Comma))
1672 break;
1673 consumeToken();
1674
1675 // We expect to see a macro name here.
1676 if (!Tok.is(MMToken::Identifier)) {
1677 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1678 break;
1679 }
1680
1681 // Consume the macro name.
1682 if (!ActiveModule->Parent) {
1683 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1684 }
1685 consumeToken();
1686 } while (true);
1687}
1688
Douglas Gregor906d66a2013-03-20 21:10:35 +00001689/// \brief Format a module-id into a string.
1690static std::string formatModuleId(const ModuleId &Id) {
1691 std::string result;
1692 {
1693 llvm::raw_string_ostream OS(result);
1694
1695 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1696 if (I)
1697 OS << ".";
1698 OS << Id[I].first;
1699 }
1700 }
1701
1702 return result;
1703}
1704
1705/// \brief Parse a conflict declaration.
1706///
1707/// module-declaration:
1708/// 'conflict' module-id ',' string-literal
1709void ModuleMapParser::parseConflict() {
1710 assert(Tok.is(MMToken::Conflict));
1711 SourceLocation ConflictLoc = consumeToken();
1712 Module::UnresolvedConflict Conflict;
1713
1714 // Parse the module-id.
1715 if (parseModuleId(Conflict.Id))
1716 return;
1717
1718 // Parse the ','.
1719 if (!Tok.is(MMToken::Comma)) {
1720 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1721 << SourceRange(ConflictLoc);
1722 return;
1723 }
1724 consumeToken();
1725
1726 // Parse the message.
1727 if (!Tok.is(MMToken::StringLiteral)) {
1728 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1729 << formatModuleId(Conflict.Id);
1730 return;
1731 }
1732 Conflict.Message = Tok.getString().str();
1733 consumeToken();
1734
1735 // Add this unresolved conflict.
1736 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1737}
1738
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001739/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001740///
1741/// module-declaration:
1742/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1743/// { inferred-module-member* }
1744///
1745/// inferred-module-member:
1746/// 'export' '*'
1747/// 'exclude' identifier
1748void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001749 assert(Tok.is(MMToken::Star));
1750 SourceLocation StarLoc = consumeToken();
1751 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001752
Douglas Gregor1e123682011-12-05 22:27:44 +00001753 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001754 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001755 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1756 Failed = true;
1757 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001758
1759 if (ActiveModule) {
1760 // Inferred modules must have umbrella directories.
1761 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1762 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1763 Failed = true;
1764 }
1765
1766 // Check for redefinition of an inferred module.
1767 if (!Failed && ActiveModule->InferSubmodules) {
1768 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1769 if (ActiveModule->InferredSubmoduleLoc.isValid())
1770 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1771 diag::note_mmap_prev_definition);
1772 Failed = true;
1773 }
1774
1775 // Check for the 'framework' keyword, which is not permitted here.
1776 if (Framework) {
1777 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1778 Framework = false;
1779 }
1780 } else if (Explicit) {
1781 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1782 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001783 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001784
Douglas Gregor1e123682011-12-05 22:27:44 +00001785 // If there were any problems with this inferred submodule, skip its body.
1786 if (Failed) {
1787 if (Tok.is(MMToken::LBrace)) {
1788 consumeToken();
1789 skipUntil(MMToken::RBrace);
1790 if (Tok.is(MMToken::RBrace))
1791 consumeToken();
1792 }
1793 HadError = true;
1794 return;
1795 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001796
1797 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001798 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001799 parseOptionalAttributes(Attrs);
1800
1801 if (ActiveModule) {
1802 // Note that we have an inferred submodule.
1803 ActiveModule->InferSubmodules = true;
1804 ActiveModule->InferredSubmoduleLoc = StarLoc;
1805 ActiveModule->InferExplicitSubmodules = Explicit;
1806 } else {
1807 // We'll be inferring framework modules for this directory.
1808 Map.InferredDirectories[Directory].InferModules = true;
1809 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1810 }
1811
Douglas Gregor1e123682011-12-05 22:27:44 +00001812 // Parse the opening brace.
1813 if (!Tok.is(MMToken::LBrace)) {
1814 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1815 HadError = true;
1816 return;
1817 }
1818 SourceLocation LBraceLoc = consumeToken();
1819
1820 // Parse the body of the inferred submodule.
1821 bool Done = false;
1822 do {
1823 switch (Tok.Kind) {
1824 case MMToken::EndOfFile:
1825 case MMToken::RBrace:
1826 Done = true;
1827 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001828
1829 case MMToken::ExcludeKeyword: {
1830 if (ActiveModule) {
1831 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001832 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001833 consumeToken();
1834 break;
1835 }
1836
1837 consumeToken();
1838 if (!Tok.is(MMToken::Identifier)) {
1839 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1840 break;
1841 }
1842
1843 Map.InferredDirectories[Directory].ExcludedModules
1844 .push_back(Tok.getString());
1845 consumeToken();
1846 break;
1847 }
1848
1849 case MMToken::ExportKeyword:
1850 if (!ActiveModule) {
1851 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001852 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001853 consumeToken();
1854 break;
1855 }
1856
Douglas Gregor1e123682011-12-05 22:27:44 +00001857 consumeToken();
1858 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001859 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001860 else
1861 Diags.Report(Tok.getLocation(),
1862 diag::err_mmap_expected_export_wildcard);
1863 consumeToken();
1864 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001865
Douglas Gregor1e123682011-12-05 22:27:44 +00001866 case MMToken::ExplicitKeyword:
1867 case MMToken::ModuleKeyword:
1868 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001869 case MMToken::PrivateKeyword:
Douglas Gregor1e123682011-12-05 22:27:44 +00001870 case MMToken::UmbrellaKeyword:
1871 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001872 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001873 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001874 consumeToken();
1875 break;
1876 }
1877 } while (!Done);
1878
1879 if (Tok.is(MMToken::RBrace))
1880 consumeToken();
1881 else {
1882 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1883 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1884 HadError = true;
1885 }
1886}
1887
Douglas Gregor82e52372012-11-06 19:39:40 +00001888/// \brief Parse optional attributes.
1889///
1890/// attributes:
1891/// attribute attributes
1892/// attribute
1893///
1894/// attribute:
1895/// [ identifier ]
1896///
1897/// \param Attrs Will be filled in with the parsed attributes.
1898///
1899/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001900bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001901 bool HadError = false;
1902
1903 while (Tok.is(MMToken::LSquare)) {
1904 // Consume the '['.
1905 SourceLocation LSquareLoc = consumeToken();
1906
1907 // Check whether we have an attribute name here.
1908 if (!Tok.is(MMToken::Identifier)) {
1909 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1910 skipUntil(MMToken::RSquare);
1911 if (Tok.is(MMToken::RSquare))
1912 consumeToken();
1913 HadError = true;
1914 }
1915
1916 // Decode the attribute name.
1917 AttributeKind Attribute
1918 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001919 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00001920 .Case("system", AT_system)
1921 .Default(AT_unknown);
1922 switch (Attribute) {
1923 case AT_unknown:
1924 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1925 << Tok.getString();
1926 break;
1927
1928 case AT_system:
1929 Attrs.IsSystem = true;
1930 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001931
1932 case AT_exhaustive:
1933 Attrs.IsExhaustive = true;
1934 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001935 }
1936 consumeToken();
1937
1938 // Consume the ']'.
1939 if (!Tok.is(MMToken::RSquare)) {
1940 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1941 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1942 skipUntil(MMToken::RSquare);
1943 HadError = true;
1944 }
1945
1946 if (Tok.is(MMToken::RSquare))
1947 consumeToken();
1948 }
1949
1950 return HadError;
1951}
1952
Douglas Gregor6a1db482011-12-09 02:04:43 +00001953/// \brief If there is a specific header search directory due the presence
1954/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1955const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1956 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1957 // If we have an umbrella directory, use that.
1958 if (Mod->hasUmbrellaDir())
1959 return Mod->getUmbrellaDir();
1960
1961 // If we have a framework directory, stop looking.
1962 if (Mod->IsFramework)
1963 return 0;
1964 }
1965
1966 return 0;
1967}
1968
Douglas Gregora30cfe52011-11-11 19:10:28 +00001969/// \brief Parse a module map file.
1970///
1971/// module-map-file:
1972/// module-declaration*
1973bool ModuleMapParser::parseModuleMapFile() {
1974 do {
1975 switch (Tok.Kind) {
1976 case MMToken::EndOfFile:
1977 return HadError;
1978
Douglas Gregor587986e2011-12-07 02:23:45 +00001979 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001980 case MMToken::ExternKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001981 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001982 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001983 parseModuleDecl();
1984 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001985
Douglas Gregor51f564f2011-12-31 04:05:44 +00001986 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00001987 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00001988 case MMToken::Conflict:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001989 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001990 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001991 case MMToken::HeaderKeyword:
1992 case MMToken::Identifier:
1993 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001994 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001995 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001996 case MMToken::Period:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001997 case MMToken::PrivateKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001998 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001999 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00002000 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00002001 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002002 case MMToken::StringLiteral:
2003 case MMToken::UmbrellaKeyword:
2004 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2005 HadError = true;
2006 consumeToken();
2007 break;
2008 }
2009 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002010}
2011
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002012bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor7005b902013-01-10 01:43:00 +00002013 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2014 = ParsedModuleMap.find(File);
2015 if (Known != ParsedModuleMap.end())
2016 return Known->second;
2017
Douglas Gregordc58aa72012-01-30 06:01:29 +00002018 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00002019 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
2020 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
2021 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00002022 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00002023
2024 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00002025 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
2026 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00002027 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002028 BuiltinIncludeDir, IsSystem);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002029 bool Result = Parser.parseModuleMapFile();
2030 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00002031 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00002032 return Result;
2033}