blob: df80a93e4db84d66df2d346feae96836900eb4d4 [file] [log] [blame]
Douglas Gregor718292f2011-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 Rosea7d03842013-02-08 22:30:41 +000015#include "clang/Basic/CharInfo.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000016#include "clang/Basic/Diagnostic.h"
Douglas Gregor811db4e2012-10-23 22:26:28 +000017#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000018#include "clang/Basic/FileManager.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Basic/TargetOptions.h"
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000021#include "clang/Lex/HeaderSearch.h"
Chandler Carruth3a022472012-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 Gregor718292f2011-11-11 19:10:28 +000027#include "llvm/Support/Allocator.h"
Douglas Gregore89dbc12011-12-06 19:39:29 +000028#include "llvm/Support/FileSystem.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000029#include "llvm/Support/Host.h"
Rafael Espindola552c1692013-06-11 22:15:02 +000030#include "llvm/Support/Path.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000031#include "llvm/Support/raw_ostream.h"
Douglas Gregor07c22b72012-09-27 14:50:15 +000032#include <stdlib.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000033#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoeadae012013-01-26 16:29:36 +000034#include <limits.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000035#endif
Douglas Gregor718292f2011-11-11 19:10:28 +000036using namespace clang;
37
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000038Module::ExportDecl
39ModuleMap::resolveExport(Module *Mod,
40 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +000041 bool Complain) const {
Douglas Gregorf5eedd02011-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 Gregorfb912652013-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 Gregor2b82c2a2011-12-02 01:47:07 +000058 // Find the starting module.
Douglas Gregorfb912652013-03-20 21:10:35 +000059 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000060 if (!Context) {
61 if (Complain)
Douglas Gregorfb912652013-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 Gregor2b82c2a2011-12-02 01:47:07 +000066 }
67
68 // Dig into the module path.
Douglas Gregorfb912652013-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 Gregor2b82c2a2011-12-02 01:47:07 +000071 if (!Sub) {
72 if (Complain)
Douglas Gregorfb912652013-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 Gregor2b82c2a2011-12-02 01:47:07 +000078 }
Douglas Gregorfb912652013-03-20 21:10:35 +000079
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000080 Context = Sub;
81 }
Douglas Gregorfb912652013-03-20 21:10:35 +000082
83 return Context;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000084}
85
Douglas Gregor6b930962013-05-03 22:58:43 +000086ModuleMap::ModuleMap(FileManager &FileMgr, DiagnosticConsumer &DC,
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000087 const LangOptions &LangOpts, const TargetInfo *Target,
88 HeaderSearch &HeaderInfo)
89 : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +000090 BuiltinIncludeDir(0), CompilingModule(0)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000091{
Dylan Noblesmithc95d8192012-02-20 14:00:23 +000092 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
93 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor811db4e2012-10-23 22:26:28 +000094 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregor6b930962013-05-03 22:58:43 +000095 Diags->setClient(new ForwardingDiagnosticConsumer(DC),
96 /*ShouldOwnClient=*/true);
Douglas Gregor718292f2011-11-11 19:10:28 +000097 SourceMgr = new SourceManager(*Diags, FileMgr);
98}
99
100ModuleMap::~ModuleMap() {
Douglas Gregor5acdf592011-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 Gregor718292f2011-11-11 19:10:28 +0000107 delete SourceMgr;
108}
109
Douglas Gregor89929282012-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 Gregor056396a2012-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 Rosea7d03842013-02-08 22:30:41 +0000122 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-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 Rosea7d03842013-02-08 22:30:41 +0000126 if (isDigit(Name[0]))
Douglas Gregor056396a2012-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 Rosea7d03842013-02-08 22:30:41 +0000130 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-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 Gregor34d52742013-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 Crowlb53e5482013-06-20 21:14:14 +0000171ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor59527662012-10-15 06:28:11 +0000172 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000173 if (Known != Headers.end()) {
Douglas Gregor59527662012-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 Crowlb53e5482013-06-20 21:14:14 +0000176 return KnownHeader();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000177
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000178 return Known->second;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000179 }
Douglas Gregor34d52742013-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 Gregor64a1fa52013-05-10 22:52:27 +0000186 HeaderInfo.loadTopLevelSystemModules();
Douglas Gregor34d52742013-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 Crowlb53e5482013-06-20 21:14:14 +0000193 return KnownHeader();
Douglas Gregor34d52742013-05-02 17:58:30 +0000194
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000195 return Known->second;
Douglas Gregor34d52742013-05-02 17:58:30 +0000196 }
197 }
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000198
Douglas Gregorb65dbff2011-11-16 23:02:25 +0000199 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000200 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregore00c8b22013-01-26 00:55:12 +0000201
Douglas Gregor74260502013-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 Gregore00c8b22013-01-26 00:55:12 +0000206 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregora89c5ac2011-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 Gregor930a85c2011-12-06 16:17:15 +0000215
216 // Search up the module stack until we find a module with an umbrella
Douglas Gregor73141fa2011-12-08 17:39:04 +0000217 // directory.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000218 Module *UmbrellaModule = Result;
Douglas Gregor73141fa2011-12-08 17:39:04 +0000219 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor930a85c2011-12-06 16:17:15 +0000220 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000221
Douglas Gregor930a85c2011-12-06 16:17:15 +0000222 if (UmbrellaModule->InferSubmodules) {
Douglas Gregora89c5ac2011-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 Gregor9458f822011-12-07 22:05:21 +0000226 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000227
Douglas Gregor70331272011-12-09 02:04:43 +0000228 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000229 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-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 Gregora89c5ac2011-12-06 01:10:29 +0000234 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor9458f822011-12-07 22:05:21 +0000235 Explicit).first;
Douglas Gregora89c5ac2011-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 Gregor930a85c2011-12-06 16:17:15 +0000242 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregora89c5ac2011-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 Gregor056396a2012-10-12 21:15:50 +0000247 SmallString<32> NameBuf;
248 StringRef Name = sanitizeFilenameAsIdentifier(
249 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000250 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor9458f822011-12-07 22:05:21 +0000251 Explicit).first;
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +0000252 Result->addTopHeader(File);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000253
254 // If inferred submodules export everything they import, add a
255 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000256 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregora89c5ac2011-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 Crowlb53e5482013-06-20 21:14:14 +0000265 Headers[File] = KnownHeader(Result, NormalHeader);
Douglas Gregor1fb5c3a2011-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 Crowlb53e5482013-06-20 21:14:14 +0000270 return KnownHeader();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000271
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000272 return Headers[File];
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000273 }
274
275 SkippedDirs.push_back(Dir);
276
Douglas Gregorb65dbff2011-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 Gregora89c5ac2011-12-06 01:10:29 +0000284 } while (Dir);
Douglas Gregorb65dbff2011-11-16 23:02:25 +0000285
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000286 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000287}
288
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000289bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
290 HeadersMap::const_iterator Known = Headers.find(Header);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000291 if (Known != Headers.end())
Douglas Gregor59527662012-10-15 06:28:11 +0000292 return !Known->second.isAvailable();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000293
294 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000295 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-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 Kyrtzidise4412642013-02-19 19:58:45 +0000301 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-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 Gregor056396a2012-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 Gregor1fb5c3a2011-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 Gregor056396a2012-10-12 21:15:50 +0000329 SmallString<32> NameBuf;
330 StringRef Name = sanitizeFilenameAsIdentifier(
331 llvm::sys::path::stem(Header->getName()),
332 NameBuf);
Douglas Gregor1fb5c3a2011-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 Kyrtzidise4412642013-02-19 19:58:45 +0000355Module *ModuleMap::findModule(StringRef Name) const {
356 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000357 if (Known != Modules.end())
358 return Known->getValue();
359
360 return 0;
361}
362
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000363Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
364 Module *Context) const {
Douglas Gregor2b82c2a2011-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 Kyrtzidise4412642013-02-19 19:58:45 +0000373Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000374 if (!Context)
375 return findModule(Name);
376
Douglas Gregoreb90e832012-01-04 23:32:19 +0000377 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000378}
379
Douglas Gregorde3ef502011-11-30 23:21:26 +0000380std::pair<Module *, bool>
Douglas Gregor69021972011-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 Gregoreb90e832012-01-04 23:32:19 +0000384 if (Module *Sub = lookupModuleQualified(Name, Parent))
385 return std::make_pair(Sub, false);
Douglas Gregor69021972011-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 Kyrtzidis6f722b42013-05-08 23:46:46 +0000390 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000391 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000392 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
393 Name == LangOpts.CurrentModule) {
394 CompilingModule = Result;
395 }
396 }
Douglas Gregor69021972011-11-30 17:33:56 +0000397 return std::make_pair(Result, true);
398}
399
Douglas Gregor9194a912012-11-06 19:39:40 +0000400bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000401 StringRef Name, bool &IsSystem) const {
Douglas Gregor9194a912012-11-06 19:39:40 +0000402 // Check whether we have already looked into the parent directory
403 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000404 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-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 Gregor11dfe6f2013-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 Gregorde3ef502011-11-30 23:21:26 +0000441Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000442ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000443 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000444 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000445 Module *Parent) {
Douglas Gregor56c64012011-11-17 01:41:17 +0000446 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000447 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
448 return Mod;
449
450 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor9194a912012-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 Gregor4ddf2222013-01-10 01:43:00 +0000455 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000456
Douglas Gregor4ddf2222013-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 Gregore00c8b22013-01-26 00:55:12 +0000461 StringRef FrameworkDirName
462 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000463
Douglas Gregor9194a912012-11-06 19:39:40 +0000464 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000465 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000466 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000467 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-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 Kyrtzidise4412642013-02-19 19:58:45 +0000471 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-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 Gregor963c5532013-06-21 16:28:10 +0000479 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor9194a912012-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 Gregor4ddf2222013-01-10 01:43:00 +0000491 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-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 Gregor56c64012011-11-17 01:41:17 +0000508 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000509 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000510 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000511 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-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 Gregore89dbc12011-12-06 19:39:29 +0000519 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
520 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora686e1b2012-01-27 19:52:33 +0000521 if (IsSystem)
522 Result->IsSystem = IsSystem;
523
Douglas Gregoreb90e832012-01-04 23:32:19 +0000524 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000525 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000526
Douglas Gregor322f6332011-12-08 18:00:48 +0000527 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000528 Result->Umbrella = UmbrellaHeader;
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000529 Headers[UmbrellaHeader] = KnownHeader(Result, NormalHeader);
Douglas Gregor4dc71832011-12-12 23:55:05 +0000530 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000531
532 // export *
533 Result->Exports.push_back(Module::ExportDecl(0, true));
534
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000535 // module * { export * }
536 Result->InferSubmodules = true;
537 Result->InferExportWildcard = true;
538
Douglas Gregore89dbc12011-12-06 19:39:29 +0000539 // Look for subframeworks.
540 llvm::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000541 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000542 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000543 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000544 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000545 for (llvm::sys::fs::directory_iterator
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000546 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000547 Dir != DirEnd && !EC; Dir.increment(EC)) {
548 if (!StringRef(Dir->path()).endswith(".framework"))
549 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000550
Douglas Gregore89dbc12011-12-06 19:39:29 +0000551 if (const DirectoryEntry *SubframeworkDir
552 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-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 Gregore00c8b22013-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 Gregor07c22b72012-09-27 14:50:15 +0000565
Douglas Gregore00c8b22013-01-26 00:55:12 +0000566 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
567 FoundParent = true;
568 break;
569 }
570 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000571
Douglas Gregore00c8b22013-01-26 00:55:12 +0000572 if (!FoundParent)
573 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000574
Douglas Gregore89dbc12011-12-06 19:39:29 +0000575 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-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 Gregore89dbc12011-12-06 19:39:29 +0000580 }
581 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000582
Douglas Gregor11dfe6f2013-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 Gregor56c64012011-11-17 01:41:17 +0000589 return Result;
590}
591
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000592void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000593 Headers[UmbrellaHeader] = KnownHeader(Mod, NormalHeader);
Douglas Gregor73141fa2011-12-08 17:39:04 +0000594 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000595 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000596}
597
Douglas Gregor524e33e2011-12-08 19:11:24 +0000598void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
599 Mod->Umbrella = UmbrellaDir;
600 UmbrellaDirs[UmbrellaDir] = Mod;
601}
602
Douglas Gregor59527662012-10-15 06:28:11 +0000603void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000604 ModuleHeaderRole Role) {
605 if (Role == ExcludedHeader) {
Douglas Gregor59527662012-10-15 06:28:11 +0000606 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000607 } else {
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000608 if (Role == PrivateHeader)
609 Mod->PrivateHeaders.push_back(Header);
610 else
611 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000612 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000613 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000614 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000615 Headers[Header] = KnownHeader(Mod, Role);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000616}
617
Douglas Gregor514b6362011-11-29 19:06:37 +0000618const FileEntry *
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000619ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregor514b6362011-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 Gregor718292f2011-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 Gregord28d1b82011-11-29 18:17:59 +0000632 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000633
634 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000635 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000636 H != HEnd; ++H) {
637 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor59527662012-10-15 06:28:11 +0000638 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000639 }
640}
641
Douglas Gregor2b82c2a2011-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 Gregorf5eedd02011-12-05 17:28:06 +0000647 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-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 Gregorfb912652013-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 Gregor0093b3c2011-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 Gregor0093b3c2011-12-05 16:33:54 +0000687
Douglas Gregor224d8a72012-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 Crowlb53e5482013-06-20 21:14:14 +0000691 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-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 Gregor0093b3c2011-12-05 16:33:54 +0000704}
705
Douglas Gregor718292f2011-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 Gregor1fb5c3a2011-12-31 04:05:44 +0000714 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000715 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000716 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000717 EndOfFile,
718 HeaderKeyword,
719 Identifier,
Douglas Gregor59527662012-10-15 06:28:11 +0000720 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000721 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000722 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000723 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000724 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000725 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000726 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000727 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000728 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000729 UmbrellaKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000730 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000731 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000732 StringLiteral,
733 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000734 RBrace,
735 LSquare,
736 RSquare
Douglas Gregor718292f2011-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 Gregor9194a912012-11-06 19:39:40 +0000760
761 /// \brief The set of attributes that can be attached to a module.
Bill Wendling44426052012-12-20 19:22:21 +0000762 struct Attributes {
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000763 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor9194a912012-11-06 19:39:40 +0000764
765 /// \brief Whether this is a system module.
766 unsigned IsSystem : 1;
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000767
768 /// \brief Whether this is an exhaustive set of configuration macros.
769 unsigned IsExhaustive : 1;
Douglas Gregor9194a912012-11-06 19:39:40 +0000770 };
Douglas Gregor718292f2011-11-11 19:10:28 +0000771
Douglas Gregor9194a912012-11-06 19:39:40 +0000772
Douglas Gregor718292f2011-11-11 19:10:28 +0000773 class ModuleMapParser {
774 Lexer &L;
775 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000776
777 /// \brief Default target information, used only for string literal
778 /// parsing.
779 const TargetInfo *Target;
780
Douglas Gregor718292f2011-11-11 19:10:28 +0000781 DiagnosticsEngine &Diags;
782 ModuleMap &Map;
783
Douglas Gregor5257fc62011-11-11 21:55:48 +0000784 /// \brief The directory that this module map resides in.
785 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +0000786
787 /// \brief The directory containing Clang-supplied headers.
788 const DirectoryEntry *BuiltinIncludeDir;
789
Douglas Gregor963c5532013-06-21 16:28:10 +0000790 /// \brief Whether this module map is in a system header directory.
791 bool IsSystem;
792
Douglas Gregor718292f2011-11-11 19:10:28 +0000793 /// \brief Whether an error occurred.
794 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000795
Douglas Gregor718292f2011-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 Gregorde3ef502011-11-30 23:21:26 +0000804 Module *ActiveModule;
Douglas Gregor718292f2011-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 Gregore7ab3662011-12-07 02:23:45 +0000812
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000813 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +0000814 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +0000815 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +0000816 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000817 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000818 void parseHeaderDecl(clang::MMToken::TokenKind,
819 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +0000820 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000821 void parseExportDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000822 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000823 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +0000824 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +0000825 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendling44426052012-12-20 19:22:21 +0000826 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor9194a912012-11-06 19:39:40 +0000827
Douglas Gregor70331272011-12-09 02:04:43 +0000828 const DirectoryEntry *getOverriddenHeaderSearchDir();
829
Douglas Gregor718292f2011-11-11 19:10:28 +0000830 public:
Douglas Gregor718292f2011-11-11 19:10:28 +0000831 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000832 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +0000833 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +0000834 ModuleMap &Map,
Douglas Gregor3ec66632012-02-02 18:42:48 +0000835 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +0000836 const DirectoryEntry *BuiltinIncludeDir,
837 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000838 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor963c5532013-06-21 16:28:10 +0000839 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
840 IsSystem(IsSystem), HadError(false), ActiveModule(0)
Douglas Gregor718292f2011-11-11 19:10:28 +0000841 {
Douglas Gregor718292f2011-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 Gregor35b13ec2013-03-20 00:22:05 +0000863 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +0000864 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +0000865 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +0000866 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000867 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +0000868 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +0000869 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000870 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000871 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +0000872 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000873 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000874 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +0000875 .Case("umbrella", MMToken::UmbrellaKeyword)
876 .Default(MMToken::Identifier);
877 break;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000878
879 case tok::comma:
880 Tok.Kind = MMToken::Comma;
881 break;
882
Douglas Gregor718292f2011-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 Gregora686e1b2012-01-27 19:52:33 +0000891 case tok::l_square:
892 Tok.Kind = MMToken::LSquare;
893 break;
894
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000895 case tok::period:
896 Tok.Kind = MMToken::Period;
897 break;
898
Douglas Gregor718292f2011-11-11 19:10:28 +0000899 case tok::r_brace:
900 Tok.Kind = MMToken::RBrace;
901 break;
902
Douglas Gregora686e1b2012-01-27 19:52:33 +0000903 case tok::r_square:
904 Tok.Kind = MMToken::RSquare;
905 break;
906
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000907 case tok::star:
908 Tok.Kind = MMToken::Star;
909 break;
910
Douglas Gregor718292f2011-11-11 19:10:28 +0000911 case tok::string_literal: {
Richard Smithd67aea22012-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 Gregor718292f2011-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 Gregora686e1b2012-01-27 19:52:33 +0000951 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +0000952 do {
953 switch (Tok.Kind) {
954 case MMToken::EndOfFile:
955 return;
956
957 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +0000958 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +0000959 return;
960
961 ++braceDepth;
962 break;
Douglas Gregora686e1b2012-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 Gregor718292f2011-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 Gregora686e1b2012-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 Gregor718292f2011-11-11 19:10:28 +0000985 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +0000986 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +0000987 return;
988 break;
989 }
990
991 consumeToken();
992 } while (true);
993}
994
Douglas Gregore7ab3662011-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 Gregora686e1b2012-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 Gregor35b13ec2013-03-20 00:22:05 +00001028 AT_system,
1029 /// \brief The 'exhaustive' attribute.
1030 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001031 };
1032}
1033
Douglas Gregor718292f2011-11-11 19:10:28 +00001034/// \brief Parse a module declaration.
1035///
1036/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001037/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001038/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1039/// { module-member* }
1040///
Douglas Gregor718292f2011-11-11 19:10:28 +00001041/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001042/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001043/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001044/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001045/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001046/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001047///
1048/// submodule-declaration:
1049/// module-declaration
1050/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001051void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001052 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-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 Gregorf2161a72011-12-06 17:16:41 +00001059 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001060 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001061 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001062 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001063
Douglas Gregorf2161a72011-12-06 17:16:41 +00001064 // Parse 'explicit' keyword, if present.
1065 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001066 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001067 Explicit = true;
1068 }
1069
1070 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001071 if (Tok.is(MMToken::FrameworkKeyword)) {
1072 consumeToken();
1073 Framework = true;
1074 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001075
1076 // Parse 'module' keyword.
1077 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001078 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001079 consumeToken();
1080 HadError = true;
1081 return;
1082 }
1083 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-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 Gregor9194a912012-11-06 19:39:40 +00001088 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001089
1090 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001091 ModuleId Id;
1092 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001093 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001094 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001095 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001096
Douglas Gregore7ab3662011-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 Gregor718292f2011-11-11 19:10:28 +00001137
Douglas Gregora686e1b2012-01-27 19:52:33 +00001138 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001139 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001140 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001141
Douglas Gregor718292f2011-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 Gregoreb90e832012-01-04 23:32:19 +00001152 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-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 Gregor718292f2011-11-11 19:10:28 +00001166 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1167 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001168 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-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 Gregoreb90e832012-01-04 23:32:19 +00001180 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1181 Explicit).first;
1182 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001183 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001184 ActiveModule->IsSystem = true;
Douglas Gregor718292f2011-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 Gregor35b13ec2013-03-20 00:22:05 +00001193
1194 case MMToken::ConfigMacros:
1195 parseConfigMacros();
1196 break;
1197
Douglas Gregorfb912652013-03-20 21:10:35 +00001198 case MMToken::Conflict:
1199 parseConflict();
1200 break;
1201
Douglas Gregor718292f2011-11-11 19:10:28 +00001202 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001203 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001204 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001205 case MMToken::ModuleKeyword:
1206 parseModuleDecl();
1207 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001208
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001209 case MMToken::ExportKeyword:
1210 parseExportDecl();
1211 break;
1212
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001213 case MMToken::RequiresKeyword:
1214 parseRequiresDecl();
1215 break;
1216
Douglas Gregor524e33e2011-12-08 19:11:24 +00001217 case MMToken::UmbrellaKeyword: {
1218 SourceLocation UmbrellaLoc = consumeToken();
1219 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001220 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001221 else
1222 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001223 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001224 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001225
Douglas Gregor59527662012-10-15 06:28:11 +00001226 case MMToken::ExcludeKeyword: {
1227 SourceLocation ExcludeLoc = consumeToken();
1228 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001229 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor59527662012-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 Crowlb53e5482013-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 Gregor322f6332011-12-08 18:00:48 +00001248 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001249 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregor718292f2011-11-11 19:10:28 +00001250 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001251
1252 case MMToken::LinkKeyword:
1253 parseLinkDecl();
1254 break;
1255
Douglas Gregor718292f2011-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 Gregor11dfe6f2013-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 Gregore7ab3662011-12-07 02:23:45 +00001278 // We're done parsing this module. Pop back to the previous module.
1279 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001280}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001281
Daniel Jasper97292842013-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 Gregor1fb5c3a2011-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 Gregor89929282012-01-30 06:01:29 +00001353 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-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 Gregorf2161a72011-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 Kramerbf8da9d2012-02-06 11:13:08 +00001365static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001366 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001367 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001368 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-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 Kramer17381a02013-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 Gregorf2161a72011-12-06 17:16:41 +00001380}
1381
Douglas Gregor718292f2011-11-11 19:10:28 +00001382/// \brief Parse a header declaration.
1383///
1384/// header-declaration:
Douglas Gregor322f6332011-12-08 18:00:48 +00001385/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor59527662012-10-15 06:28:11 +00001386/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001387void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1388 SourceLocation LeadingLoc) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001389 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001390 consumeToken();
1391
Douglas Gregor718292f2011-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 Gregore7ab3662011-12-07 02:23:45 +00001399 std::string FileName = Tok.getString();
Douglas Gregor718292f2011-11-11 19:10:28 +00001400 SourceLocation FileNameLoc = consumeToken();
1401
Douglas Gregor524e33e2011-12-08 19:11:24 +00001402 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001403 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Douglas Gregor524e33e2011-12-08 19:11:24 +00001404 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1405 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001406 HadError = true;
1407 return;
1408 }
1409
Douglas Gregor5257fc62011-11-11 21:55:48 +00001410 // Look for this file.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001411 const FileEntry *File = 0;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001412 const FileEntry *BuiltinFile = 0;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001413 SmallString<128> PathName;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001414 if (llvm::sys::path::is_absolute(FileName)) {
1415 PathName = FileName;
1416 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor70331272011-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 Gregore7ab3662011-12-07 02:23:45 +00001421 } else {
1422 // Search for the header file within the search directory.
Douglas Gregor70331272011-12-09 02:04:43 +00001423 PathName = Directory->getName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001424 unsigned PathLength = PathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001425
Douglas Gregorf2161a72011-12-06 17:16:41 +00001426 if (ActiveModule->isPartOfFramework()) {
1427 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001428
1429 // Check whether this file is in the public headers.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001430 llvm::sys::path::append(PathName, "Headers", FileName);
Douglas Gregore7ab3662011-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 Kramer17381a02013-06-28 16:25:46 +00001436 llvm::sys::path::append(PathName, "PrivateHeaders", FileName);
Douglas Gregore7ab3662011-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 Gregor3ec66632012-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 Crowlb53e5482013-06-20 21:14:14 +00001447 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1448 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1449 isBuiltinHeader(FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001450 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor3ec66632012-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 Gregorf2161a72011-12-06 17:16:41 +00001462 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001463 }
Douglas Gregor755b2052011-11-17 22:09:43 +00001464
Douglas Gregor5257fc62011-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 Gregore7ab3662011-12-07 02:23:45 +00001467 if (File) {
Douglas Gregor59527662012-10-15 06:28:11 +00001468 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor5257fc62011-11-11 21:55:48 +00001469 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001470 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor5257fc62011-11-11 21:55:48 +00001471 HadError = true;
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001472 } else if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001473 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001474 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001475 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001476 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001477 HadError = true;
1478 } else {
1479 // Record this umbrella header.
1480 Map.setUmbrellaHeader(ActiveModule, File);
1481 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00001482 } else {
Douglas Gregor322f6332011-12-08 18:00:48 +00001483 // Record this header.
Lawrence Crowlb53e5482013-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 Gregor3ec66632012-02-02 18:42:48 +00001493
1494 // If there is a builtin counterpart to this file, add it now.
1495 if (BuiltinFile)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001496 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001497 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001498 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001499 // Ignore excluded header files. They're optional anyway.
1500
Douglas Gregor5257fc62011-11-11 21:55:48 +00001501 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001502 << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
Douglas Gregor5257fc62011-11-11 21:55:48 +00001503 HadError = true;
1504 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001505}
1506
Douglas Gregor524e33e2011-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 Noblesmith2c1dd272012-02-05 02:13:05 +00001536 SmallString<128> PathName;
Douglas Gregor524e33e2011-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 Gregor2b82c2a2011-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 Gregorf5eedd02011-12-05 17:28:06 +00001592 consumeToken();
Douglas Gregor2b82c2a2011-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 Gregor6ddfca92013-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 Gregor35b13ec2013-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 Gregorfb912652013-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 Gregor6ddfca92013-01-14 17:21:00 +00001739/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-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 Gregor73441092011-12-05 22:27:44 +00001749 assert(Tok.is(MMToken::Star));
1750 SourceLocation StarLoc = consumeToken();
1751 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00001752
Douglas Gregor73441092011-12-05 22:27:44 +00001753 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00001754 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00001755 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1756 Failed = true;
1757 }
Douglas Gregor9194a912012-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 Gregor73441092011-12-05 22:27:44 +00001783 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001784
Douglas Gregor73441092011-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 Gregor9194a912012-11-06 19:39:40 +00001796
1797 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00001798 Attributes Attrs;
Douglas Gregor9194a912012-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 Gregor73441092011-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 Gregor9194a912012-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 Gregor162405d2012-11-06 19:41:11 +00001832 << (ActiveModule != 0);
Douglas Gregor9194a912012-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 Gregor162405d2012-11-06 19:41:11 +00001852 << (ActiveModule != 0);
Douglas Gregor9194a912012-11-06 19:39:40 +00001853 consumeToken();
1854 break;
1855 }
1856
Douglas Gregor73441092011-12-05 22:27:44 +00001857 consumeToken();
1858 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00001859 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00001860 else
1861 Diags.Report(Tok.getLocation(),
1862 diag::err_mmap_expected_export_wildcard);
1863 consumeToken();
1864 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00001865
Douglas Gregor73441092011-12-05 22:27:44 +00001866 case MMToken::ExplicitKeyword:
1867 case MMToken::ModuleKeyword:
1868 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001869 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00001870 case MMToken::UmbrellaKeyword:
1871 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00001872 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00001873 << (ActiveModule != 0);
Douglas Gregor73441092011-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 Gregor9194a912012-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 Wendling44426052012-12-20 19:22:21 +00001900bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-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 Gregor35b13ec2013-03-20 00:22:05 +00001919 .Case("exhaustive", AT_exhaustive)
Douglas Gregor9194a912012-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 Gregor35b13ec2013-03-20 00:22:05 +00001931
1932 case AT_exhaustive:
1933 Attrs.IsExhaustive = true;
1934 break;
Douglas Gregor9194a912012-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 Gregor70331272011-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 Gregor718292f2011-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 Gregore7ab3662011-12-07 02:23:45 +00001979 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001980 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001981 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00001982 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001983 parseModuleDecl();
1984 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001985
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001986 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001987 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00001988 case MMToken::Conflict:
Douglas Gregor59527662012-10-15 06:28:11 +00001989 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001990 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001991 case MMToken::HeaderKeyword:
1992 case MMToken::Identifier:
1993 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001994 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001995 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001996 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001997 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001998 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001999 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002000 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002001 case MMToken::Star:
Douglas Gregor718292f2011-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 Gregor718292f2011-11-11 19:10:28 +00002010}
2011
Douglas Gregor963c5532013-06-21 16:28:10 +00002012bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor4ddf2222013-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 Gregor89929282012-01-30 06:01:29 +00002018 assert(Target != 0 && "Missing target information");
Douglas Gregor718292f2011-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 Gregor4ddf2222013-01-10 01:43:00 +00002022 return ParsedModuleMap[File] = true;
Douglas Gregor718292f2011-11-11 19:10:28 +00002023
2024 // Parse this module map file.
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002025 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
2026 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00002027 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor963c5532013-06-21 16:28:10 +00002028 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002029 bool Result = Parser.parseModuleMapFile();
2030 Diags->getClient()->EndSourceFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002031 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002032 return Result;
2033}