blob: 0f12af361a45acb006ff4e3484c126c3cdffe6a0 [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);
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000390 if (LangOpts.CurrentModule == Name) {
391 SourceModule = Result;
392 SourceModuleName = Name;
393 }
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000394 if (!Parent) {
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000395 Modules[Name] = Result;
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000396 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
397 Name == LangOpts.CurrentModule) {
398 CompilingModule = Result;
399 }
400 }
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000401 return std::make_pair(Result, true);
402}
403
Douglas Gregor82e52372012-11-06 19:39:40 +0000404bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000405 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000406 // Check whether we have already looked into the parent directory
407 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000408 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000409 inferred = InferredDirectories.find(ParentDir);
410 if (inferred == InferredDirectories.end())
411 return false;
412
413 if (!inferred->second.InferModules)
414 return false;
415
416 // We're allowed to infer for this directory, but make sure it's okay
417 // to infer this particular module.
418 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
419 inferred->second.ExcludedModules.end(),
420 Name) == inferred->second.ExcludedModules.end();
421
422 if (canInfer && inferred->second.InferSystemModules)
423 IsSystem = true;
424
425 return canInfer;
426}
427
Douglas Gregor8767dc22013-01-14 17:57:51 +0000428/// \brief For a framework module, infer the framework against which we
429/// should link.
430static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
431 FileManager &FileMgr) {
432 assert(Mod->IsFramework && "Can only infer linking for framework modules");
433 assert(!Mod->isSubFramework() &&
434 "Can only infer linking for top-level frameworks");
435
436 SmallString<128> LibName;
437 LibName += FrameworkDir->getName();
438 llvm::sys::path::append(LibName, Mod->Name);
439 if (FileMgr.getFile(LibName)) {
440 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
441 /*IsFramework=*/true));
442 }
443}
444
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000445Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000446ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000447 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000448 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000449 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000450 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000451 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
452 return Mod;
453
454 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000455
456 // If the framework has a parent path from which we're allowed to infer
457 // a framework module, do so.
458 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000459 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000460
Douglas Gregor7005b902013-01-10 01:43:00 +0000461 // Note: as an egregious but useful hack we use the real path here, because
462 // we might be looking at an embedded framework that symlinks out to a
463 // top-level framework, and we need to infer as if we were naming the
464 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000465 StringRef FrameworkDirName
466 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000467
Douglas Gregor82e52372012-11-06 19:39:40 +0000468 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000469 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000470 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000471 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000472 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
473 // Check whether we have already looked into the parent directory
474 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000475 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000476 inferred = InferredDirectories.find(ParentDir);
477 if (inferred == InferredDirectories.end()) {
478 // We haven't looked here before. Load a module map, if there is
479 // one.
480 SmallString<128> ModMapPath = Parent;
481 llvm::sys::path::append(ModMapPath, "module.map");
482 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000483 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor82e52372012-11-06 19:39:40 +0000484 inferred = InferredDirectories.find(ParentDir);
485 }
486
487 if (inferred == InferredDirectories.end())
488 inferred = InferredDirectories.insert(
489 std::make_pair(ParentDir, InferredDirectory())).first;
490 }
491
492 if (inferred->second.InferModules) {
493 // We're allowed to infer for this directory, but make sure it's okay
494 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000495 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000496 canInfer = std::find(inferred->second.ExcludedModules.begin(),
497 inferred->second.ExcludedModules.end(),
498 Name) == inferred->second.ExcludedModules.end();
499
500 if (inferred->second.InferSystemModules)
501 IsSystem = true;
502 }
503 }
504 }
505
506 // If we're not allowed to infer a framework module, don't.
507 if (!canInfer)
508 return 0;
509 }
510
511
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000512 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000513 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramerceb6dc82013-06-28 16:25:46 +0000514 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000515 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000516
517 // FIXME: If there's no umbrella header, we could probably scan the
518 // framework to load *everything*. But, it's not clear that this is a good
519 // idea.
520 if (!UmbrellaHeader)
521 return 0;
522
Douglas Gregorac252a32011-12-06 19:39:29 +0000523 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
524 /*IsFramework=*/true, /*IsExplicit=*/false);
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000525 if (LangOpts.CurrentModule == ModuleName) {
526 SourceModule = Result;
527 SourceModuleName = ModuleName;
528 }
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000529 if (IsSystem)
530 Result->IsSystem = IsSystem;
531
Douglas Gregorb7a78192012-01-04 23:32:19 +0000532 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000533 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000534
Douglas Gregor489ad432011-12-08 18:00:48 +0000535 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000536 Result->Umbrella = UmbrellaHeader;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000537 Headers[UmbrellaHeader] = KnownHeader(Result, NormalHeader);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000538 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000539
540 // export *
541 Result->Exports.push_back(Module::ExportDecl(0, true));
542
Douglas Gregore209e502011-12-06 01:10:29 +0000543 // module * { export * }
544 Result->InferSubmodules = true;
545 Result->InferExportWildcard = true;
546
Douglas Gregorac252a32011-12-06 19:39:29 +0000547 // Look for subframeworks.
548 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000549 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000550 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000551 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer0f599ac2013-09-11 11:23:15 +0000552 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000553 for (llvm::sys::fs::directory_iterator
Benjamin Kramer0f599ac2013-09-11 11:23:15 +0000554 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000555 Dir != DirEnd && !EC; Dir.increment(EC)) {
556 if (!StringRef(Dir->path()).endswith(".framework"))
557 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000558
Douglas Gregorac252a32011-12-06 19:39:29 +0000559 if (const DirectoryEntry *SubframeworkDir
560 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000561 // Note: as an egregious but useful hack, we use the real path here and
562 // check whether it is actually a subdirectory of the parent directory.
563 // This will not be the case if the 'subframework' is actually a symlink
564 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000565 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
566 bool FoundParent = false;
567 do {
568 // Get the parent directory name.
569 SubframeworkDirName
570 = llvm::sys::path::parent_path(SubframeworkDirName);
571 if (SubframeworkDirName.empty())
572 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000573
Douglas Gregor713b7c02013-01-26 00:55:12 +0000574 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
575 FoundParent = true;
576 break;
577 }
578 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000579
Douglas Gregor713b7c02013-01-26 00:55:12 +0000580 if (!FoundParent)
581 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000582
Douglas Gregorac252a32011-12-06 19:39:29 +0000583 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000584 SmallString<32> NameBuf;
585 inferFrameworkModule(sanitizeFilenameAsIdentifier(
586 llvm::sys::path::stem(Dir->path()), NameBuf),
587 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000588 }
589 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000590
Douglas Gregor8767dc22013-01-14 17:57:51 +0000591 // If the module is a top-level framework, automatically link against the
592 // framework.
593 if (!Result->isSubFramework()) {
594 inferFrameworkLink(Result, FrameworkDir, FileMgr);
595 }
596
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000597 return Result;
598}
599
Douglas Gregore209e502011-12-06 01:10:29 +0000600void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000601 Headers[UmbrellaHeader] = KnownHeader(Mod, NormalHeader);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000602 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000603 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000604}
605
Douglas Gregor77d029f2011-12-08 19:11:24 +0000606void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
607 Mod->Umbrella = UmbrellaDir;
608 UmbrellaDirs[UmbrellaDir] = Mod;
609}
610
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000611void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000612 ModuleHeaderRole Role) {
613 if (Role == ExcludedHeader) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000614 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000615 } else {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000616 if (Role == PrivateHeader)
617 Mod->PrivateHeaders.push_back(Header);
618 else
619 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000620 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000621 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000622 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000623 Headers[Header] = KnownHeader(Mod, Role);
Douglas Gregore209e502011-12-06 01:10:29 +0000624}
625
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000626const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000627ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000628 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
629 return 0;
630
631 return SourceMgr->getFileEntryForID(
632 SourceMgr->getFileID(Module->DefinitionLoc));
633}
634
Douglas Gregora30cfe52011-11-11 19:10:28 +0000635void ModuleMap::dump() {
636 llvm::errs() << "Modules:";
637 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
638 MEnd = Modules.end();
639 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000640 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000641
642 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000643 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000644 H != HEnd; ++H) {
645 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000646 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000647 }
648}
649
Douglas Gregor90db2602011-12-02 01:47:07 +0000650bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
651 bool HadError = false;
652 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
653 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
654 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000655 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000656 Mod->Exports.push_back(Export);
657 else
658 HadError = true;
659 }
660 Mod->UnresolvedExports.clear();
661 return HadError;
662}
663
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000664bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
665 bool HadError = false;
666 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
667 Module *DirectUse =
668 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
669 if (DirectUse)
670 Mod->DirectUses.push_back(DirectUse);
671 else
672 HadError = true;
673 }
674 Mod->UnresolvedDirectUses.clear();
675 return HadError;
676}
677
Douglas Gregor906d66a2013-03-20 21:10:35 +0000678bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
679 bool HadError = false;
680 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
681 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
682 Mod, Complain);
683 if (!OtherMod) {
684 HadError = true;
685 continue;
686 }
687
688 Module::Conflict Conflict;
689 Conflict.Other = OtherMod;
690 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
691 Mod->Conflicts.push_back(Conflict);
692 }
693 Mod->UnresolvedConflicts.clear();
694 return HadError;
695}
696
Douglas Gregor55988682011-12-05 16:33:54 +0000697Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
698 if (Loc.isInvalid())
699 return 0;
700
701 // Use the expansion location to determine which module we're in.
702 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
703 if (!ExpansionLoc.isFileID())
704 return 0;
705
706
707 const SourceManager &SrcMgr = Loc.getManager();
708 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000709
Douglas Gregor303aae92012-01-06 17:19:32 +0000710 while (const FileEntry *ExpansionFile
711 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
712 // Find the module that owns this header (if any).
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000713 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor303aae92012-01-06 17:19:32 +0000714 return Mod;
715
716 // No module owns this header, so look up the inclusion chain to see if
717 // any included header has an associated module.
718 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
719 if (IncludeLoc.isInvalid())
720 return 0;
721
722 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
723 }
724
725 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000726}
727
Douglas Gregora30cfe52011-11-11 19:10:28 +0000728//----------------------------------------------------------------------------//
729// Module map file parser
730//----------------------------------------------------------------------------//
731
732namespace clang {
733 /// \brief A token in a module map file.
734 struct MMToken {
735 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000736 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000737 ConfigMacros,
Douglas Gregor906d66a2013-03-20 21:10:35 +0000738 Conflict,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000739 EndOfFile,
740 HeaderKeyword,
741 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000742 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000743 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000744 ExportKeyword,
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000745 ExternKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000746 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000747 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000748 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000749 Period,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000750 PrivateKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000751 UmbrellaKeyword,
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000752 UseKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000753 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000754 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000755 StringLiteral,
756 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000757 RBrace,
758 LSquare,
759 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000760 } Kind;
761
762 unsigned Location;
763 unsigned StringLength;
764 const char *StringData;
765
766 void clear() {
767 Kind = EndOfFile;
768 Location = 0;
769 StringLength = 0;
770 StringData = 0;
771 }
772
773 bool is(TokenKind K) const { return Kind == K; }
774
775 SourceLocation getLocation() const {
776 return SourceLocation::getFromRawEncoding(Location);
777 }
778
779 StringRef getString() const {
780 return StringRef(StringData, StringLength);
781 }
782 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000783
784 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000785 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000786 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000787
788 /// \brief Whether this is a system module.
789 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000790
791 /// \brief Whether this is an exhaustive set of configuration macros.
792 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000793 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000794
Douglas Gregor82e52372012-11-06 19:39:40 +0000795
Douglas Gregora30cfe52011-11-11 19:10:28 +0000796 class ModuleMapParser {
797 Lexer &L;
798 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000799
800 /// \brief Default target information, used only for string literal
801 /// parsing.
802 const TargetInfo *Target;
803
Douglas Gregora30cfe52011-11-11 19:10:28 +0000804 DiagnosticsEngine &Diags;
805 ModuleMap &Map;
806
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000807 /// \brief The directory that this module map resides in.
808 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000809
810 /// \brief The directory containing Clang-supplied headers.
811 const DirectoryEntry *BuiltinIncludeDir;
812
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000813 /// \brief Whether this module map is in a system header directory.
814 bool IsSystem;
815
Douglas Gregora30cfe52011-11-11 19:10:28 +0000816 /// \brief Whether an error occurred.
817 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000818
Douglas Gregora30cfe52011-11-11 19:10:28 +0000819 /// \brief Stores string data for the various string literals referenced
820 /// during parsing.
821 llvm::BumpPtrAllocator StringData;
822
823 /// \brief The current token.
824 MMToken Tok;
825
826 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000827 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000828
829 /// \brief Consume the current token and return its location.
830 SourceLocation consumeToken();
831
832 /// \brief Skip tokens until we reach the a token with the given kind
833 /// (or the end of the file).
834 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000835
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000836 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000837 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000838 void parseModuleDecl();
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000839 void parseExternModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000840 void parseRequiresDecl();
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000841 void parseHeaderDecl(clang::MMToken::TokenKind,
842 SourceLocation LeadingLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000843 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000844 void parseExportDecl();
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000845 void parseUseDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000846 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000847 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000848 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000849 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000850 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000851
Douglas Gregor6a1db482011-12-09 02:04:43 +0000852 const DirectoryEntry *getOverriddenHeaderSearchDir();
853
Douglas Gregora30cfe52011-11-11 19:10:28 +0000854 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000855 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000856 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000857 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000858 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000859 const DirectoryEntry *Directory,
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000860 const DirectoryEntry *BuiltinIncludeDir,
861 bool IsSystem)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000862 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000863 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
864 IsSystem(IsSystem), HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000865 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000866 Tok.clear();
867 consumeToken();
868 }
869
870 bool parseModuleMapFile();
871 };
872}
873
874SourceLocation ModuleMapParser::consumeToken() {
875retry:
876 SourceLocation Result = Tok.getLocation();
877 Tok.clear();
878
879 Token LToken;
880 L.LexFromRawLexer(LToken);
881 Tok.Location = LToken.getLocation().getRawEncoding();
882 switch (LToken.getKind()) {
883 case tok::raw_identifier:
884 Tok.StringData = LToken.getRawIdentifierData();
885 Tok.StringLength = LToken.getLength();
886 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000887 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000888 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000889 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000890 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000891 .Case("export", MMToken::ExportKeyword)
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000892 .Case("extern", MMToken::ExternKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000893 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000894 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000895 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000896 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000897 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000898 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000899 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000900 .Case("use", MMToken::UseKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000901 .Default(MMToken::Identifier);
902 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000903
904 case tok::comma:
905 Tok.Kind = MMToken::Comma;
906 break;
907
Douglas Gregora30cfe52011-11-11 19:10:28 +0000908 case tok::eof:
909 Tok.Kind = MMToken::EndOfFile;
910 break;
911
912 case tok::l_brace:
913 Tok.Kind = MMToken::LBrace;
914 break;
915
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000916 case tok::l_square:
917 Tok.Kind = MMToken::LSquare;
918 break;
919
Douglas Gregor90db2602011-12-02 01:47:07 +0000920 case tok::period:
921 Tok.Kind = MMToken::Period;
922 break;
923
Douglas Gregora30cfe52011-11-11 19:10:28 +0000924 case tok::r_brace:
925 Tok.Kind = MMToken::RBrace;
926 break;
927
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000928 case tok::r_square:
929 Tok.Kind = MMToken::RSquare;
930 break;
931
Douglas Gregor90db2602011-12-02 01:47:07 +0000932 case tok::star:
933 Tok.Kind = MMToken::Star;
934 break;
935
Douglas Gregora30cfe52011-11-11 19:10:28 +0000936 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000937 if (LToken.hasUDSuffix()) {
938 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
939 HadError = true;
940 goto retry;
941 }
942
Douglas Gregora30cfe52011-11-11 19:10:28 +0000943 // Parse the string literal.
944 LangOptions LangOpts;
945 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
946 if (StringLiteral.hadError)
947 goto retry;
948
949 // Copy the string literal into our string data allocator.
950 unsigned Length = StringLiteral.GetStringLength();
951 char *Saved = StringData.Allocate<char>(Length + 1);
952 memcpy(Saved, StringLiteral.GetString().data(), Length);
953 Saved[Length] = 0;
954
955 // Form the token.
956 Tok.Kind = MMToken::StringLiteral;
957 Tok.StringData = Saved;
958 Tok.StringLength = Length;
959 break;
960 }
961
962 case tok::comment:
963 goto retry;
964
965 default:
966 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
967 HadError = true;
968 goto retry;
969 }
970
971 return Result;
972}
973
974void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
975 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000976 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000977 do {
978 switch (Tok.Kind) {
979 case MMToken::EndOfFile:
980 return;
981
982 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000983 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000984 return;
985
986 ++braceDepth;
987 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000988
989 case MMToken::LSquare:
990 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
991 return;
992
993 ++squareDepth;
994 break;
995
Douglas Gregora30cfe52011-11-11 19:10:28 +0000996 case MMToken::RBrace:
997 if (braceDepth > 0)
998 --braceDepth;
999 else if (Tok.is(K))
1000 return;
1001 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001002
1003 case MMToken::RSquare:
1004 if (squareDepth > 0)
1005 --squareDepth;
1006 else if (Tok.is(K))
1007 return;
1008 break;
1009
Douglas Gregora30cfe52011-11-11 19:10:28 +00001010 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001011 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +00001012 return;
1013 break;
1014 }
1015
1016 consumeToken();
1017 } while (true);
1018}
1019
Douglas Gregor587986e2011-12-07 02:23:45 +00001020/// \brief Parse a module-id.
1021///
1022/// module-id:
1023/// identifier
1024/// identifier '.' module-id
1025///
1026/// \returns true if an error occurred, false otherwise.
1027bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1028 Id.clear();
1029 do {
1030 if (Tok.is(MMToken::Identifier)) {
1031 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1032 consumeToken();
1033 } else {
1034 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1035 return true;
1036 }
1037
1038 if (!Tok.is(MMToken::Period))
1039 break;
1040
1041 consumeToken();
1042 } while (true);
1043
1044 return false;
1045}
1046
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001047namespace {
1048 /// \brief Enumerates the known attributes.
1049 enum AttributeKind {
1050 /// \brief An unknown attribute.
1051 AT_unknown,
1052 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001053 AT_system,
1054 /// \brief The 'exhaustive' attribute.
1055 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001056 };
1057}
1058
Douglas Gregora30cfe52011-11-11 19:10:28 +00001059/// \brief Parse a module declaration.
1060///
1061/// module-declaration:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001062/// 'extern' 'module' module-id string-literal
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001063/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1064/// { module-member* }
1065///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001066/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001067/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001068/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001069/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001070/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001071/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001072///
1073/// submodule-declaration:
1074/// module-declaration
1075/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001076void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001077 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001078 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1079 if (Tok.is(MMToken::ExternKeyword)) {
1080 parseExternModuleDecl();
1081 return;
1082 }
1083
Douglas Gregord620a842011-12-06 17:16:41 +00001084 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001085 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001086 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001087 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001088
Douglas Gregord620a842011-12-06 17:16:41 +00001089 // Parse 'explicit' keyword, if present.
1090 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001091 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001092 Explicit = true;
1093 }
1094
1095 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001096 if (Tok.is(MMToken::FrameworkKeyword)) {
1097 consumeToken();
1098 Framework = true;
1099 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001100
1101 // Parse 'module' keyword.
1102 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001103 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001104 consumeToken();
1105 HadError = true;
1106 return;
1107 }
1108 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001109
1110 // If we have a wildcard for the module name, this is an inferred submodule.
1111 // Parse it.
1112 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001113 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001114
1115 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001116 ModuleId Id;
1117 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001118 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001119 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001120 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001121
Douglas Gregor587986e2011-12-07 02:23:45 +00001122 if (ActiveModule) {
1123 if (Id.size() > 1) {
1124 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1125 << SourceRange(Id.front().second, Id.back().second);
1126
1127 HadError = true;
1128 return;
1129 }
1130 } else if (Id.size() == 1 && Explicit) {
1131 // Top-level modules can't be explicit.
1132 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1133 Explicit = false;
1134 ExplicitLoc = SourceLocation();
1135 HadError = true;
1136 }
1137
1138 Module *PreviousActiveModule = ActiveModule;
1139 if (Id.size() > 1) {
1140 // This module map defines a submodule. Go find the module of which it
1141 // is a submodule.
1142 ActiveModule = 0;
1143 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1144 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1145 ActiveModule = Next;
1146 continue;
1147 }
1148
1149 if (ActiveModule) {
1150 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1151 << Id[I].first << ActiveModule->getTopLevelModule();
1152 } else {
1153 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1154 }
1155 HadError = true;
1156 return;
1157 }
1158 }
1159
1160 StringRef ModuleName = Id.back().first;
1161 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001162
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001163 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001164 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001165 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001166
Douglas Gregora30cfe52011-11-11 19:10:28 +00001167 // Parse the opening brace.
1168 if (!Tok.is(MMToken::LBrace)) {
1169 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1170 << ModuleName;
1171 HadError = true;
1172 return;
1173 }
1174 SourceLocation LBraceLoc = consumeToken();
1175
1176 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001177 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001178 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1179 // Skip the module definition.
1180 skipUntil(MMToken::RBrace);
1181 if (Tok.is(MMToken::RBrace))
1182 consumeToken();
1183 else {
1184 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1185 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1186 HadError = true;
1187 }
1188 return;
1189 }
1190
Douglas Gregora30cfe52011-11-11 19:10:28 +00001191 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1192 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001193 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001194
1195 // Skip the module definition.
1196 skipUntil(MMToken::RBrace);
1197 if (Tok.is(MMToken::RBrace))
1198 consumeToken();
1199
1200 HadError = true;
1201 return;
1202 }
1203
1204 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001205 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1206 Explicit).first;
1207 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001208 if (Attrs.IsSystem || IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001209 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001210
1211 bool Done = false;
1212 do {
1213 switch (Tok.Kind) {
1214 case MMToken::EndOfFile:
1215 case MMToken::RBrace:
1216 Done = true;
1217 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001218
1219 case MMToken::ConfigMacros:
1220 parseConfigMacros();
1221 break;
1222
Douglas Gregor906d66a2013-03-20 21:10:35 +00001223 case MMToken::Conflict:
1224 parseConflict();
1225 break;
1226
Douglas Gregora30cfe52011-11-11 19:10:28 +00001227 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001228 case MMToken::ExternKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001229 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001230 case MMToken::ModuleKeyword:
1231 parseModuleDecl();
1232 break;
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001233
Douglas Gregor90db2602011-12-02 01:47:07 +00001234 case MMToken::ExportKeyword:
1235 parseExportDecl();
1236 break;
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001237
1238 case MMToken::UseKeyword:
1239 parseUseDecl();
1240 break;
Douglas Gregor90db2602011-12-02 01:47:07 +00001241
Douglas Gregor51f564f2011-12-31 04:05:44 +00001242 case MMToken::RequiresKeyword:
1243 parseRequiresDecl();
1244 break;
1245
Douglas Gregor77d029f2011-12-08 19:11:24 +00001246 case MMToken::UmbrellaKeyword: {
1247 SourceLocation UmbrellaLoc = consumeToken();
1248 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001249 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +00001250 else
1251 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001252 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001253 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001254
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001255 case MMToken::ExcludeKeyword: {
1256 SourceLocation ExcludeLoc = consumeToken();
1257 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001258 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001259 } else {
1260 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1261 << "exclude";
1262 }
1263 break;
1264 }
1265
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001266 case MMToken::PrivateKeyword: {
1267 SourceLocation PrivateLoc = consumeToken();
1268 if (Tok.is(MMToken::HeaderKeyword)) {
1269 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1270 } else {
1271 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1272 << "private";
1273 }
1274 break;
1275 }
1276
Douglas Gregor489ad432011-12-08 18:00:48 +00001277 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001278 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001279 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001280
1281 case MMToken::LinkKeyword:
1282 parseLinkDecl();
1283 break;
1284
Douglas Gregora30cfe52011-11-11 19:10:28 +00001285 default:
1286 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1287 consumeToken();
1288 break;
1289 }
1290 } while (!Done);
1291
1292 if (Tok.is(MMToken::RBrace))
1293 consumeToken();
1294 else {
1295 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1296 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1297 HadError = true;
1298 }
1299
Douglas Gregor8767dc22013-01-14 17:57:51 +00001300 // If the active module is a top-level framework, and there are no link
1301 // libraries, automatically link against the framework.
1302 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1303 ActiveModule->LinkLibraries.empty()) {
1304 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1305 }
1306
Douglas Gregor587986e2011-12-07 02:23:45 +00001307 // We're done parsing this module. Pop back to the previous module.
1308 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001309}
Douglas Gregord620a842011-12-06 17:16:41 +00001310
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001311/// \brief Parse an extern module declaration.
1312///
1313/// extern module-declaration:
1314/// 'extern' 'module' module-id string-literal
1315void ModuleMapParser::parseExternModuleDecl() {
1316 assert(Tok.is(MMToken::ExternKeyword));
1317 consumeToken(); // 'extern' keyword
1318
1319 // Parse 'module' keyword.
1320 if (!Tok.is(MMToken::ModuleKeyword)) {
1321 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1322 consumeToken();
1323 HadError = true;
1324 return;
1325 }
1326 consumeToken(); // 'module' keyword
1327
1328 // Parse the module name.
1329 ModuleId Id;
1330 if (parseModuleId(Id)) {
1331 HadError = true;
1332 return;
1333 }
1334
1335 // Parse the referenced module map file name.
1336 if (!Tok.is(MMToken::StringLiteral)) {
1337 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1338 HadError = true;
1339 return;
1340 }
1341 std::string FileName = Tok.getString();
1342 consumeToken(); // filename
1343
1344 StringRef FileNameRef = FileName;
1345 SmallString<128> ModuleMapFileName;
1346 if (llvm::sys::path::is_relative(FileNameRef)) {
1347 ModuleMapFileName += Directory->getName();
1348 llvm::sys::path::append(ModuleMapFileName, FileName);
1349 FileNameRef = ModuleMapFileName.str();
1350 }
1351 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1352 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1353}
1354
Douglas Gregor51f564f2011-12-31 04:05:44 +00001355/// \brief Parse a requires declaration.
1356///
1357/// requires-declaration:
1358/// 'requires' feature-list
1359///
1360/// feature-list:
1361/// identifier ',' feature-list
1362/// identifier
1363void ModuleMapParser::parseRequiresDecl() {
1364 assert(Tok.is(MMToken::RequiresKeyword));
1365
1366 // Parse 'requires' keyword.
1367 consumeToken();
1368
1369 // Parse the feature-list.
1370 do {
1371 if (!Tok.is(MMToken::Identifier)) {
1372 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1373 HadError = true;
1374 return;
1375 }
1376
1377 // Consume the feature name.
1378 std::string Feature = Tok.getString();
1379 consumeToken();
1380
1381 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001382 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001383
1384 if (!Tok.is(MMToken::Comma))
1385 break;
1386
1387 // Consume the comma.
1388 consumeToken();
1389 } while (true);
1390}
1391
Douglas Gregord620a842011-12-06 17:16:41 +00001392/// \brief Append to \p Paths the set of paths needed to get to the
1393/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001394static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001395 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001396 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001397 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001398 for (; Mod; Mod = Mod->Parent) {
1399 if (Mod->IsFramework)
1400 Paths.push_back(Mod->Name);
1401 }
1402
1403 if (Paths.empty())
1404 return;
1405
1406 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001407 for (unsigned I = Paths.size() - 1; I != 0; --I)
1408 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregord620a842011-12-06 17:16:41 +00001409}
1410
Douglas Gregora30cfe52011-11-11 19:10:28 +00001411/// \brief Parse a header declaration.
1412///
1413/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001414/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001415/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001416void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1417 SourceLocation LeadingLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001418 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001419 consumeToken();
1420
Douglas Gregora30cfe52011-11-11 19:10:28 +00001421 // Parse the header name.
1422 if (!Tok.is(MMToken::StringLiteral)) {
1423 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1424 << "header";
1425 HadError = true;
1426 return;
1427 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001428 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001429 SourceLocation FileNameLoc = consumeToken();
1430
Douglas Gregor77d029f2011-12-08 19:11:24 +00001431 // Check whether we already have an umbrella.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001432 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Douglas Gregor77d029f2011-12-08 19:11:24 +00001433 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1434 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001435 HadError = true;
1436 return;
1437 }
1438
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001439 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001440 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001441 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001442 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001443 if (llvm::sys::path::is_absolute(FileName)) {
1444 PathName = FileName;
1445 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001446 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1447 PathName = Dir->getName();
1448 llvm::sys::path::append(PathName, FileName);
1449 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001450 } else {
1451 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001452 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001453 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001454
Douglas Gregord620a842011-12-06 17:16:41 +00001455 if (ActiveModule->isPartOfFramework()) {
1456 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001457
1458 // Check whether this file is in the public headers.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001459 llvm::sys::path::append(PathName, "Headers", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001460 File = SourceMgr.getFileManager().getFile(PathName);
1461
1462 if (!File) {
1463 // Check whether this file is in the private headers.
1464 PathName.resize(PathLength);
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001465 llvm::sys::path::append(PathName, "PrivateHeaders", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001466 File = SourceMgr.getFileManager().getFile(PathName);
1467 }
1468 } else {
1469 // Lookup for normal headers.
1470 llvm::sys::path::append(PathName, FileName);
1471 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001472
1473 // If this is a system module with a top-level header, this header
1474 // may have a counterpart (or replacement) in the set of headers
1475 // supplied by Clang. Find that builtin header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001476 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1477 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1478 isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001479 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001480 llvm::sys::path::append(BuiltinPathName, FileName);
1481 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1482
1483 // If Clang supplies this header but the underlying system does not,
1484 // just silently swap in our builtin version. Otherwise, we'll end
1485 // up adding both (later).
1486 if (!File && BuiltinFile) {
1487 File = BuiltinFile;
1488 BuiltinFile = 0;
1489 }
1490 }
Douglas Gregord620a842011-12-06 17:16:41 +00001491 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001492 }
Douglas Gregora8654052011-11-17 22:09:43 +00001493
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001494 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1495 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001496 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001497 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001498 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001499 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001500 HadError = true;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001501 } else if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001502 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001503 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001504 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001505 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001506 HadError = true;
1507 } else {
1508 // Record this umbrella header.
1509 Map.setUmbrellaHeader(ActiveModule, File);
1510 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001511 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001512 // Record this header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001513 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1514 if (LeadingToken == MMToken::ExcludeKeyword)
1515 Role = ModuleMap::ExcludedHeader;
1516 else if (LeadingToken == MMToken::PrivateKeyword)
1517 Role = ModuleMap::PrivateHeader;
1518 else
1519 assert(LeadingToken == MMToken::HeaderKeyword);
1520
1521 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001522
1523 // If there is a builtin counterpart to this file, add it now.
1524 if (BuiltinFile)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001525 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001526 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001527 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor71f49f52012-11-15 19:47:16 +00001528 // Ignore excluded header files. They're optional anyway.
1529
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001530 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001531 << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001532 HadError = true;
1533 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001534}
1535
Douglas Gregor77d029f2011-12-08 19:11:24 +00001536/// \brief Parse an umbrella directory declaration.
1537///
1538/// umbrella-dir-declaration:
1539/// umbrella string-literal
1540void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1541 // Parse the directory name.
1542 if (!Tok.is(MMToken::StringLiteral)) {
1543 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1544 << "umbrella";
1545 HadError = true;
1546 return;
1547 }
1548
1549 std::string DirName = Tok.getString();
1550 SourceLocation DirNameLoc = consumeToken();
1551
1552 // Check whether we already have an umbrella.
1553 if (ActiveModule->Umbrella) {
1554 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1555 << ActiveModule->getFullModuleName();
1556 HadError = true;
1557 return;
1558 }
1559
1560 // Look for this file.
1561 const DirectoryEntry *Dir = 0;
1562 if (llvm::sys::path::is_absolute(DirName))
1563 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1564 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001565 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001566 PathName = Directory->getName();
1567 llvm::sys::path::append(PathName, DirName);
1568 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1569 }
1570
1571 if (!Dir) {
1572 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1573 << DirName;
1574 HadError = true;
1575 return;
1576 }
1577
1578 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1579 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1580 << OwningModule->getFullModuleName();
1581 HadError = true;
1582 return;
1583 }
1584
1585 // Record this umbrella directory.
1586 Map.setUmbrellaDir(ActiveModule, Dir);
1587}
1588
Douglas Gregor90db2602011-12-02 01:47:07 +00001589/// \brief Parse a module export declaration.
1590///
1591/// export-declaration:
1592/// 'export' wildcard-module-id
1593///
1594/// wildcard-module-id:
1595/// identifier
1596/// '*'
1597/// identifier '.' wildcard-module-id
1598void ModuleMapParser::parseExportDecl() {
1599 assert(Tok.is(MMToken::ExportKeyword));
1600 SourceLocation ExportLoc = consumeToken();
1601
1602 // Parse the module-id with an optional wildcard at the end.
1603 ModuleId ParsedModuleId;
1604 bool Wildcard = false;
1605 do {
1606 if (Tok.is(MMToken::Identifier)) {
1607 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1608 Tok.getLocation()));
1609 consumeToken();
1610
1611 if (Tok.is(MMToken::Period)) {
1612 consumeToken();
1613 continue;
1614 }
1615
1616 break;
1617 }
1618
1619 if(Tok.is(MMToken::Star)) {
1620 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001621 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001622 break;
1623 }
1624
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001625 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor90db2602011-12-02 01:47:07 +00001626 HadError = true;
1627 return;
1628 } while (true);
1629
1630 Module::UnresolvedExportDecl Unresolved = {
1631 ExportLoc, ParsedModuleId, Wildcard
1632 };
1633 ActiveModule->UnresolvedExports.push_back(Unresolved);
1634}
1635
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001636/// \brief Parse a module uses declaration.
1637///
1638/// uses-declaration:
1639/// 'uses' wildcard-module-id
1640void ModuleMapParser::parseUseDecl() {
1641 assert(Tok.is(MMToken::UseKeyword));
1642 consumeToken();
1643 // Parse the module-id.
1644 ModuleId ParsedModuleId;
1645
1646 do {
1647 if (Tok.is(MMToken::Identifier)) {
1648 ParsedModuleId.push_back(
1649 std::make_pair(Tok.getString(), Tok.getLocation()));
1650 consumeToken();
1651
1652 if (Tok.is(MMToken::Period)) {
1653 consumeToken();
1654 continue;
1655 }
1656
1657 break;
1658 }
1659
1660 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
1661 HadError = true;
1662 return;
1663 } while (true);
1664
1665 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1666}
1667
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001668/// \brief Parse a link declaration.
1669///
1670/// module-declaration:
1671/// 'link' 'framework'[opt] string-literal
1672void ModuleMapParser::parseLinkDecl() {
1673 assert(Tok.is(MMToken::LinkKeyword));
1674 SourceLocation LinkLoc = consumeToken();
1675
1676 // Parse the optional 'framework' keyword.
1677 bool IsFramework = false;
1678 if (Tok.is(MMToken::FrameworkKeyword)) {
1679 consumeToken();
1680 IsFramework = true;
1681 }
1682
1683 // Parse the library name
1684 if (!Tok.is(MMToken::StringLiteral)) {
1685 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1686 << IsFramework << SourceRange(LinkLoc);
1687 HadError = true;
1688 return;
1689 }
1690
1691 std::string LibraryName = Tok.getString();
1692 consumeToken();
1693 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1694 IsFramework));
1695}
1696
Douglas Gregor63a72682013-03-20 00:22:05 +00001697/// \brief Parse a configuration macro declaration.
1698///
1699/// module-declaration:
1700/// 'config_macros' attributes[opt] config-macro-list?
1701///
1702/// config-macro-list:
1703/// identifier (',' identifier)?
1704void ModuleMapParser::parseConfigMacros() {
1705 assert(Tok.is(MMToken::ConfigMacros));
1706 SourceLocation ConfigMacrosLoc = consumeToken();
1707
1708 // Only top-level modules can have configuration macros.
1709 if (ActiveModule->Parent) {
1710 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1711 }
1712
1713 // Parse the optional attributes.
1714 Attributes Attrs;
1715 parseOptionalAttributes(Attrs);
1716 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1717 ActiveModule->ConfigMacrosExhaustive = true;
1718 }
1719
1720 // If we don't have an identifier, we're done.
1721 if (!Tok.is(MMToken::Identifier))
1722 return;
1723
1724 // Consume the first identifier.
1725 if (!ActiveModule->Parent) {
1726 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1727 }
1728 consumeToken();
1729
1730 do {
1731 // If there's a comma, consume it.
1732 if (!Tok.is(MMToken::Comma))
1733 break;
1734 consumeToken();
1735
1736 // We expect to see a macro name here.
1737 if (!Tok.is(MMToken::Identifier)) {
1738 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1739 break;
1740 }
1741
1742 // Consume the macro name.
1743 if (!ActiveModule->Parent) {
1744 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1745 }
1746 consumeToken();
1747 } while (true);
1748}
1749
Douglas Gregor906d66a2013-03-20 21:10:35 +00001750/// \brief Format a module-id into a string.
1751static std::string formatModuleId(const ModuleId &Id) {
1752 std::string result;
1753 {
1754 llvm::raw_string_ostream OS(result);
1755
1756 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1757 if (I)
1758 OS << ".";
1759 OS << Id[I].first;
1760 }
1761 }
1762
1763 return result;
1764}
1765
1766/// \brief Parse a conflict declaration.
1767///
1768/// module-declaration:
1769/// 'conflict' module-id ',' string-literal
1770void ModuleMapParser::parseConflict() {
1771 assert(Tok.is(MMToken::Conflict));
1772 SourceLocation ConflictLoc = consumeToken();
1773 Module::UnresolvedConflict Conflict;
1774
1775 // Parse the module-id.
1776 if (parseModuleId(Conflict.Id))
1777 return;
1778
1779 // Parse the ','.
1780 if (!Tok.is(MMToken::Comma)) {
1781 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1782 << SourceRange(ConflictLoc);
1783 return;
1784 }
1785 consumeToken();
1786
1787 // Parse the message.
1788 if (!Tok.is(MMToken::StringLiteral)) {
1789 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1790 << formatModuleId(Conflict.Id);
1791 return;
1792 }
1793 Conflict.Message = Tok.getString().str();
1794 consumeToken();
1795
1796 // Add this unresolved conflict.
1797 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1798}
1799
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001800/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001801///
1802/// module-declaration:
1803/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1804/// { inferred-module-member* }
1805///
1806/// inferred-module-member:
1807/// 'export' '*'
1808/// 'exclude' identifier
1809void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001810 assert(Tok.is(MMToken::Star));
1811 SourceLocation StarLoc = consumeToken();
1812 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001813
Douglas Gregor1e123682011-12-05 22:27:44 +00001814 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001815 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001816 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1817 Failed = true;
1818 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001819
1820 if (ActiveModule) {
1821 // Inferred modules must have umbrella directories.
1822 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1823 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1824 Failed = true;
1825 }
1826
1827 // Check for redefinition of an inferred module.
1828 if (!Failed && ActiveModule->InferSubmodules) {
1829 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1830 if (ActiveModule->InferredSubmoduleLoc.isValid())
1831 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1832 diag::note_mmap_prev_definition);
1833 Failed = true;
1834 }
1835
1836 // Check for the 'framework' keyword, which is not permitted here.
1837 if (Framework) {
1838 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1839 Framework = false;
1840 }
1841 } else if (Explicit) {
1842 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1843 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001844 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001845
Douglas Gregor1e123682011-12-05 22:27:44 +00001846 // If there were any problems with this inferred submodule, skip its body.
1847 if (Failed) {
1848 if (Tok.is(MMToken::LBrace)) {
1849 consumeToken();
1850 skipUntil(MMToken::RBrace);
1851 if (Tok.is(MMToken::RBrace))
1852 consumeToken();
1853 }
1854 HadError = true;
1855 return;
1856 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001857
1858 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001859 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001860 parseOptionalAttributes(Attrs);
1861
1862 if (ActiveModule) {
1863 // Note that we have an inferred submodule.
1864 ActiveModule->InferSubmodules = true;
1865 ActiveModule->InferredSubmoduleLoc = StarLoc;
1866 ActiveModule->InferExplicitSubmodules = Explicit;
1867 } else {
1868 // We'll be inferring framework modules for this directory.
1869 Map.InferredDirectories[Directory].InferModules = true;
1870 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1871 }
1872
Douglas Gregor1e123682011-12-05 22:27:44 +00001873 // Parse the opening brace.
1874 if (!Tok.is(MMToken::LBrace)) {
1875 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1876 HadError = true;
1877 return;
1878 }
1879 SourceLocation LBraceLoc = consumeToken();
1880
1881 // Parse the body of the inferred submodule.
1882 bool Done = false;
1883 do {
1884 switch (Tok.Kind) {
1885 case MMToken::EndOfFile:
1886 case MMToken::RBrace:
1887 Done = true;
1888 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001889
1890 case MMToken::ExcludeKeyword: {
1891 if (ActiveModule) {
1892 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001893 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001894 consumeToken();
1895 break;
1896 }
1897
1898 consumeToken();
1899 if (!Tok.is(MMToken::Identifier)) {
1900 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1901 break;
1902 }
1903
1904 Map.InferredDirectories[Directory].ExcludedModules
1905 .push_back(Tok.getString());
1906 consumeToken();
1907 break;
1908 }
1909
1910 case MMToken::ExportKeyword:
1911 if (!ActiveModule) {
1912 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001913 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001914 consumeToken();
1915 break;
1916 }
1917
Douglas Gregor1e123682011-12-05 22:27:44 +00001918 consumeToken();
1919 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001920 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001921 else
1922 Diags.Report(Tok.getLocation(),
1923 diag::err_mmap_expected_export_wildcard);
1924 consumeToken();
1925 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001926
Douglas Gregor1e123682011-12-05 22:27:44 +00001927 case MMToken::ExplicitKeyword:
1928 case MMToken::ModuleKeyword:
1929 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001930 case MMToken::PrivateKeyword:
Douglas Gregor1e123682011-12-05 22:27:44 +00001931 case MMToken::UmbrellaKeyword:
1932 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001933 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001934 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001935 consumeToken();
1936 break;
1937 }
1938 } while (!Done);
1939
1940 if (Tok.is(MMToken::RBrace))
1941 consumeToken();
1942 else {
1943 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1944 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1945 HadError = true;
1946 }
1947}
1948
Douglas Gregor82e52372012-11-06 19:39:40 +00001949/// \brief Parse optional attributes.
1950///
1951/// attributes:
1952/// attribute attributes
1953/// attribute
1954///
1955/// attribute:
1956/// [ identifier ]
1957///
1958/// \param Attrs Will be filled in with the parsed attributes.
1959///
1960/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001961bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001962 bool HadError = false;
1963
1964 while (Tok.is(MMToken::LSquare)) {
1965 // Consume the '['.
1966 SourceLocation LSquareLoc = consumeToken();
1967
1968 // Check whether we have an attribute name here.
1969 if (!Tok.is(MMToken::Identifier)) {
1970 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1971 skipUntil(MMToken::RSquare);
1972 if (Tok.is(MMToken::RSquare))
1973 consumeToken();
1974 HadError = true;
1975 }
1976
1977 // Decode the attribute name.
1978 AttributeKind Attribute
1979 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001980 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00001981 .Case("system", AT_system)
1982 .Default(AT_unknown);
1983 switch (Attribute) {
1984 case AT_unknown:
1985 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1986 << Tok.getString();
1987 break;
1988
1989 case AT_system:
1990 Attrs.IsSystem = true;
1991 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001992
1993 case AT_exhaustive:
1994 Attrs.IsExhaustive = true;
1995 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001996 }
1997 consumeToken();
1998
1999 // Consume the ']'.
2000 if (!Tok.is(MMToken::RSquare)) {
2001 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2002 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2003 skipUntil(MMToken::RSquare);
2004 HadError = true;
2005 }
2006
2007 if (Tok.is(MMToken::RSquare))
2008 consumeToken();
2009 }
2010
2011 return HadError;
2012}
2013
Douglas Gregor6a1db482011-12-09 02:04:43 +00002014/// \brief If there is a specific header search directory due the presence
2015/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
2016const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
2017 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
2018 // If we have an umbrella directory, use that.
2019 if (Mod->hasUmbrellaDir())
2020 return Mod->getUmbrellaDir();
2021
2022 // If we have a framework directory, stop looking.
2023 if (Mod->IsFramework)
2024 return 0;
2025 }
2026
2027 return 0;
2028}
2029
Douglas Gregora30cfe52011-11-11 19:10:28 +00002030/// \brief Parse a module map file.
2031///
2032/// module-map-file:
2033/// module-declaration*
2034bool ModuleMapParser::parseModuleMapFile() {
2035 do {
2036 switch (Tok.Kind) {
2037 case MMToken::EndOfFile:
2038 return HadError;
2039
Douglas Gregor587986e2011-12-07 02:23:45 +00002040 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00002041 case MMToken::ExternKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002042 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00002043 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002044 parseModuleDecl();
2045 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00002046
Douglas Gregor51f564f2011-12-31 04:05:44 +00002047 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00002048 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00002049 case MMToken::Conflict:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00002050 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00002051 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002052 case MMToken::HeaderKeyword:
2053 case MMToken::Identifier:
2054 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00002055 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00002056 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00002057 case MMToken::Period:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00002058 case MMToken::PrivateKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002059 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00002060 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00002061 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00002062 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002063 case MMToken::StringLiteral:
2064 case MMToken::UmbrellaKeyword:
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00002065 case MMToken::UseKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002066 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2067 HadError = true;
2068 consumeToken();
2069 break;
2070 }
2071 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002072}
2073
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002074bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor7005b902013-01-10 01:43:00 +00002075 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2076 = ParsedModuleMap.find(File);
2077 if (Known != ParsedModuleMap.end())
2078 return Known->second;
2079
Douglas Gregordc58aa72012-01-30 06:01:29 +00002080 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00002081 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
2082 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
2083 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00002084 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00002085
2086 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00002087 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
2088 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00002089 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002090 BuiltinIncludeDir, IsSystem);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002091 bool Result = Parser.parseModuleMapFile();
2092 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00002093 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00002094 return Result;
2095}