blob: e78806dc50b28d9ae79af3d489eddcdff9fd096c [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)
Stephen Hines651f13c2014-04-23 16:59:28 -070062 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
Douglas Gregor906d66a2013-03-20 21:10:35 +000063 << 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)
Stephen Hines651f13c2014-04-23 16:59:28 -070073 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Douglas Gregor906d66a2013-03-20 21:10:35 +000074 << 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
Stephen Hines651f13c2014-04-23 16:59:28 -070086ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000087 const LangOptions &LangOpts, const TargetInfo *Target,
88 HeaderSearch &HeaderInfo)
Stephen Hines651f13c2014-04-23 16:59:28 -070089 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
Manuel Klimekee0cd372013-10-24 07:51:24 +000090 HeaderInfo(HeaderInfo), BuiltinIncludeDir(0), CompilingModule(0),
Stephen Hines651f13c2014-04-23 16:59:28 -070091 SourceModule(0) {}
Douglas Gregora30cfe52011-11-11 19:10:28 +000092
93ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +000094 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
95 IEnd = Modules.end();
96 I != IEnd; ++I) {
97 delete I->getValue();
98 }
Douglas Gregora30cfe52011-11-11 19:10:28 +000099}
100
Douglas Gregordc58aa72012-01-30 06:01:29 +0000101void ModuleMap::setTarget(const TargetInfo &Target) {
102 assert((!this->Target || this->Target == &Target) &&
103 "Improper target override");
104 this->Target = &Target;
105}
106
Douglas Gregor8b48e082012-10-12 21:15:50 +0000107/// \brief "Sanitize" a filename so that it can be used as an identifier.
108static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
109 SmallVectorImpl<char> &Buffer) {
110 if (Name.empty())
111 return Name;
112
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000113 if (!isValidIdentifier(Name)) {
Douglas Gregor8b48e082012-10-12 21:15:50 +0000114 // If we don't already have something with the form of an identifier,
115 // create a buffer with the sanitized name.
116 Buffer.clear();
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000117 if (isDigit(Name[0]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000118 Buffer.push_back('_');
119 Buffer.reserve(Buffer.size() + Name.size());
120 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000121 if (isIdentifierBody(Name[I]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000122 Buffer.push_back(Name[I]);
123 else
124 Buffer.push_back('_');
125 }
126
127 Name = StringRef(Buffer.data(), Buffer.size());
128 }
129
130 while (llvm::StringSwitch<bool>(Name)
131#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
132#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
133#include "clang/Basic/TokenKinds.def"
134 .Default(false)) {
135 if (Name.data() != Buffer.data())
136 Buffer.append(Name.begin(), Name.end());
137 Buffer.push_back('_');
138 Name = StringRef(Buffer.data(), Buffer.size());
139 }
140
141 return Name;
142}
143
Douglas Gregordb3910b2013-05-02 17:58:30 +0000144/// \brief Determine whether the given file name is the name of a builtin
145/// header, supplied by Clang to replace, override, or augment existing system
146/// headers.
147static bool isBuiltinHeader(StringRef FileName) {
148 return llvm::StringSwitch<bool>(FileName)
149 .Case("float.h", true)
150 .Case("iso646.h", true)
151 .Case("limits.h", true)
152 .Case("stdalign.h", true)
153 .Case("stdarg.h", true)
154 .Case("stdbool.h", true)
155 .Case("stddef.h", true)
156 .Case("stdint.h", true)
157 .Case("tgmath.h", true)
158 .Case("unwind.h", true)
159 .Default(false);
160}
161
Stephen Hines651f13c2014-04-23 16:59:28 -0700162ModuleMap::HeadersMap::iterator
163ModuleMap::findKnownHeader(const FileEntry *File) {
164 HeadersMap::iterator Known = Headers.find(File);
165 if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
166 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
167 HeaderInfo.loadTopLevelSystemModules();
168 return Headers.find(File);
169 }
170 return Known;
171}
172
173// Returns 'true' if 'RequestingModule directly uses 'RequestedModule'.
174static bool directlyUses(const Module *RequestingModule,
175 const Module *RequestedModule) {
176 return std::find(RequestingModule->DirectUses.begin(),
177 RequestingModule->DirectUses.end(),
178 RequestedModule) != RequestingModule->DirectUses.end();
179}
180
181static bool violatesPrivateInclude(Module *RequestingModule,
182 const FileEntry *IncFileEnt,
183 ModuleMap::ModuleHeaderRole Role,
184 Module *RequestedModule) {
185 #ifndef NDEBUG
186 // Check for consistency between the module header role
187 // as obtained from the lookup and as obtained from the module.
188 // This check is not cheap, so enable it only for debugging.
189 SmallVectorImpl<const FileEntry *> &PvtHdrs
190 = RequestedModule->PrivateHeaders;
191 SmallVectorImpl<const FileEntry *>::iterator Look
192 = std::find(PvtHdrs.begin(), PvtHdrs.end(), IncFileEnt);
193 bool IsPrivate = Look != PvtHdrs.end();
194 assert((IsPrivate && Role == ModuleMap::PrivateHeader)
195 || (!IsPrivate && Role != ModuleMap::PrivateHeader));
196 #endif
197 return Role == ModuleMap::PrivateHeader &&
198 RequestedModule->getTopLevelModule() != RequestingModule;
199}
200
201void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
202 SourceLocation FilenameLoc,
203 StringRef Filename,
204 const FileEntry *File) {
205 // No errors for indirect modules. This may be a bit of a problem for modules
206 // with no source files.
207 if (RequestingModule != SourceModule)
208 return;
209
210 if (RequestingModule)
211 resolveUses(RequestingModule, /*Complain=*/false);
212
213 HeadersMap::iterator Known = findKnownHeader(File);
214 if (Known == Headers.end())
215 return;
216
217 Module *Private = NULL;
218 Module *NotUsed = NULL;
219 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
220 E = Known->second.end();
221 I != E; ++I) {
222 // Excluded headers don't really belong to a module.
223 if (I->getRole() == ModuleMap::ExcludedHeader)
224 continue;
225
226 // If 'File' is part of 'RequestingModule' we can definitely include it.
227 if (I->getModule() == RequestingModule)
228 return;
229
230 // Remember private headers for later printing of a diagnostic.
231 if (violatesPrivateInclude(RequestingModule, File, I->getRole(),
232 I->getModule())) {
233 Private = I->getModule();
234 continue;
235 }
236
237 // If uses need to be specified explicitly, we are only allowed to return
238 // modules that are explicitly used by the requesting module.
239 if (RequestingModule && LangOpts.ModulesDeclUse &&
240 !directlyUses(RequestingModule, I->getModule())) {
241 NotUsed = I->getModule();
242 continue;
243 }
244
245 // We have found a module that we can happily use.
246 return;
247 }
248
249 // We have found a header, but it is private.
250 if (Private != NULL) {
251 Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module)
252 << Filename;
253 return;
254 }
255
256 // We have found a module, but we don't use it.
257 if (NotUsed != NULL) {
258 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
259 << RequestingModule->getFullModuleName() << Filename;
260 return;
261 }
262
263 // Headers for which we have not found a module are fine to include.
264}
265
Daniel Jasperc6417092013-10-22 08:09:47 +0000266ModuleMap::KnownHeader
267ModuleMap::findModuleForHeader(const FileEntry *File,
268 Module *RequestingModule) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700269 HeadersMap::iterator Known = findKnownHeader(File);
270
Douglas Gregor51f564f2011-12-31 04:05:44 +0000271 if (Known != Headers.end()) {
Daniel Jasperc6417092013-10-22 08:09:47 +0000272 ModuleMap::KnownHeader Result = KnownHeader();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000273
Daniel Jasperc6417092013-10-22 08:09:47 +0000274 // Iterate over all modules that 'File' is part of to find the best fit.
275 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
276 E = Known->second.end();
277 I != E; ++I) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700278 // Cannot use a module if the header is excluded in it.
279 if (I->getRole() == ModuleMap::ExcludedHeader)
280 continue;
281
282 // Cannot use a module if it is unavailable.
283 if (!I->getModule()->isAvailable())
Daniel Jasperc6417092013-10-22 08:09:47 +0000284 continue;
285
286 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
287 // module we are looking for.
288 if (I->getModule() == RequestingModule)
289 return *I;
290
291 // If uses need to be specified explicitly, we are only allowed to return
292 // modules that are explicitly used by the requesting module.
293 if (RequestingModule && LangOpts.ModulesDeclUse &&
Stephen Hines651f13c2014-04-23 16:59:28 -0700294 !directlyUses(RequestingModule, I->getModule()))
Daniel Jasperc6417092013-10-22 08:09:47 +0000295 continue;
Stephen Hines651f13c2014-04-23 16:59:28 -0700296
Daniel Jasperc6417092013-10-22 08:09:47 +0000297 Result = *I;
298 // If 'File' is a public header of this module, this is as good as we
299 // are going to get.
Stephen Hines651f13c2014-04-23 16:59:28 -0700300 // FIXME: If we have a RequestingModule, we should prefer the header from
301 // that module.
Daniel Jasperc6417092013-10-22 08:09:47 +0000302 if (I->getRole() == ModuleMap::NormalHeader)
303 break;
304 }
305 return Result;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000306 }
Douglas Gregordb3910b2013-05-02 17:58:30 +0000307
Douglas Gregoradb97992011-11-16 23:02:25 +0000308 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000309 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000310
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000311 // Note: as an egregious but useful hack we use the real path here, because
312 // frameworks moving from top-level frameworks to embedded frameworks tend
313 // to be symlinked from the top-level location to the embedded location,
314 // and we need to resolve lookups as if we had found the embedded location.
Manuel Klimekee0cd372013-10-24 07:51:24 +0000315 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000316
317 // Keep walking up the directory hierarchy, looking for a directory with
318 // an umbrella header.
319 do {
320 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
321 = UmbrellaDirs.find(Dir);
322 if (KnownDir != UmbrellaDirs.end()) {
323 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000324
325 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000326 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000327 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000328 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000329 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000330
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000331 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000332 // Infer submodules for each of the directories we found between
333 // the directory of the umbrella header and the directory where
334 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000335 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000336
Douglas Gregor6a1db482011-12-09 02:04:43 +0000337 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000338 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000339 SmallString<32> NameBuf;
340 StringRef Name = sanitizeFilenameAsIdentifier(
341 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
342 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000343 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000344 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000345
346 // Associate the module and the directory.
347 UmbrellaDirs[SkippedDirs[I-1]] = Result;
348
349 // If inferred submodules export everything they import, add a
350 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000351 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000352 Result->Exports.push_back(Module::ExportDecl(0, true));
353 }
354
355 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000356 SmallString<32> NameBuf;
357 StringRef Name = sanitizeFilenameAsIdentifier(
358 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000359 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000360 Explicit).first;
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +0000361 Result->addTopHeader(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000362
363 // If inferred submodules export everything they import, add a
364 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000365 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000366 Result->Exports.push_back(Module::ExportDecl(0, true));
367 } else {
368 // Record each of the directories we stepped through as being part of
369 // the module we found, since the umbrella header covers them all.
370 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
371 UmbrellaDirs[SkippedDirs[I]] = Result;
372 }
373
Daniel Jasperc6417092013-10-22 08:09:47 +0000374 Headers[File].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor51f564f2011-12-31 04:05:44 +0000375
376 // If a header corresponds to an unavailable module, don't report
377 // that it maps to anything.
378 if (!Result->isAvailable())
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000379 return KnownHeader();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000380
Daniel Jasperc6417092013-10-22 08:09:47 +0000381 return Headers[File].back();
Douglas Gregore209e502011-12-06 01:10:29 +0000382 }
383
384 SkippedDirs.push_back(Dir);
385
Douglas Gregoradb97992011-11-16 23:02:25 +0000386 // Retrieve our parent path.
387 DirName = llvm::sys::path::parent_path(DirName);
388 if (DirName.empty())
389 break;
390
391 // Resolve the parent path to a directory entry.
Manuel Klimekee0cd372013-10-24 07:51:24 +0000392 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000393 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000394
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000395 return KnownHeader();
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000396}
397
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000398bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
399 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasperc6417092013-10-22 08:09:47 +0000400 if (Known != Headers.end()) {
401 for (SmallVectorImpl<KnownHeader>::const_iterator
402 I = Known->second.begin(),
403 E = Known->second.end();
404 I != E; ++I) {
405 if (I->isAvailable())
406 return false;
407 }
408 return true;
409 }
Douglas Gregor51f564f2011-12-31 04:05:44 +0000410
411 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000412 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000413 StringRef DirName = Dir->getName();
414
415 // Keep walking up the directory hierarchy, looking for a directory with
416 // an umbrella header.
417 do {
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000418 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor51f564f2011-12-31 04:05:44 +0000419 = UmbrellaDirs.find(Dir);
420 if (KnownDir != UmbrellaDirs.end()) {
421 Module *Found = KnownDir->second;
422 if (!Found->isAvailable())
423 return true;
424
425 // Search up the module stack until we find a module with an umbrella
426 // directory.
427 Module *UmbrellaModule = Found;
428 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
429 UmbrellaModule = UmbrellaModule->Parent;
430
431 if (UmbrellaModule->InferSubmodules) {
432 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
433 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000434 SmallString<32> NameBuf;
435 StringRef Name = sanitizeFilenameAsIdentifier(
436 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
437 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000438 Found = lookupModuleQualified(Name, Found);
439 if (!Found)
440 return false;
441 if (!Found->isAvailable())
442 return true;
443 }
444
445 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000446 SmallString<32> NameBuf;
447 StringRef Name = sanitizeFilenameAsIdentifier(
448 llvm::sys::path::stem(Header->getName()),
449 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000450 Found = lookupModuleQualified(Name, Found);
451 if (!Found)
452 return false;
453 }
454
455 return !Found->isAvailable();
456 }
457
458 SkippedDirs.push_back(Dir);
459
460 // Retrieve our parent path.
461 DirName = llvm::sys::path::parent_path(DirName);
462 if (DirName.empty())
463 break;
464
465 // Resolve the parent path to a directory entry.
Manuel Klimekee0cd372013-10-24 07:51:24 +0000466 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000467 } while (Dir);
468
469 return false;
470}
471
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000472Module *ModuleMap::findModule(StringRef Name) const {
473 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor484535e2011-11-11 23:20:24 +0000474 if (Known != Modules.end())
475 return Known->getValue();
476
477 return 0;
478}
479
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000480Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
481 Module *Context) const {
Douglas Gregor90db2602011-12-02 01:47:07 +0000482 for(; Context; Context = Context->Parent) {
483 if (Module *Sub = lookupModuleQualified(Name, Context))
484 return Sub;
485 }
486
487 return findModule(Name);
488}
489
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000490Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor90db2602011-12-02 01:47:07 +0000491 if (!Context)
492 return findModule(Name);
493
Douglas Gregorb7a78192012-01-04 23:32:19 +0000494 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000495}
496
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000497std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000498ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
499 bool IsExplicit) {
500 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000501 if (Module *Sub = lookupModuleQualified(Name, Parent))
502 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000503
504 // Create a new module with this name.
505 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
506 IsExplicit);
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000507 if (LangOpts.CurrentModule == Name) {
508 SourceModule = Result;
509 SourceModuleName = Name;
510 }
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000511 if (!Parent) {
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000512 Modules[Name] = Result;
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000513 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
514 Name == LangOpts.CurrentModule) {
515 CompilingModule = Result;
516 }
517 }
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000518 return std::make_pair(Result, true);
519}
520
Douglas Gregor82e52372012-11-06 19:39:40 +0000521bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000522 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000523 // Check whether we have already looked into the parent directory
524 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000525 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000526 inferred = InferredDirectories.find(ParentDir);
527 if (inferred == InferredDirectories.end())
528 return false;
529
530 if (!inferred->second.InferModules)
531 return false;
532
533 // We're allowed to infer for this directory, but make sure it's okay
534 // to infer this particular module.
535 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
536 inferred->second.ExcludedModules.end(),
537 Name) == inferred->second.ExcludedModules.end();
538
539 if (canInfer && inferred->second.InferSystemModules)
540 IsSystem = true;
541
542 return canInfer;
543}
544
Douglas Gregor8767dc22013-01-14 17:57:51 +0000545/// \brief For a framework module, infer the framework against which we
546/// should link.
547static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
548 FileManager &FileMgr) {
549 assert(Mod->IsFramework && "Can only infer linking for framework modules");
550 assert(!Mod->isSubFramework() &&
551 "Can only infer linking for top-level frameworks");
552
553 SmallString<128> LibName;
554 LibName += FrameworkDir->getName();
555 llvm::sys::path::append(LibName, Mod->Name);
556 if (FileMgr.getFile(LibName)) {
557 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
558 /*IsFramework=*/true));
559 }
560}
561
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000562Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000563ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000564 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000565 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000566 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000567 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000568 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
569 return Mod;
570
Manuel Klimekee0cd372013-10-24 07:51:24 +0000571 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000572
573 // If the framework has a parent path from which we're allowed to infer
574 // a framework module, do so.
575 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000576 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000577
Douglas Gregor7005b902013-01-10 01:43:00 +0000578 // Note: as an egregious but useful hack we use the real path here, because
579 // we might be looking at an embedded framework that symlinks out to a
580 // top-level framework, and we need to infer as if we were naming the
581 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000582 StringRef FrameworkDirName
Manuel Klimekee0cd372013-10-24 07:51:24 +0000583 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000584
Douglas Gregor82e52372012-11-06 19:39:40 +0000585 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000586 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000587 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000588 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000589 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
590 // Check whether we have already looked into the parent directory
591 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000592 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000593 inferred = InferredDirectories.find(ParentDir);
594 if (inferred == InferredDirectories.end()) {
595 // We haven't looked here before. Load a module map, if there is
596 // one.
Stephen Hines651f13c2014-04-23 16:59:28 -0700597 bool IsFrameworkDir = Parent.endswith(".framework");
598 if (const FileEntry *ModMapFile =
599 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000600 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor82e52372012-11-06 19:39:40 +0000601 inferred = InferredDirectories.find(ParentDir);
602 }
603
604 if (inferred == InferredDirectories.end())
605 inferred = InferredDirectories.insert(
606 std::make_pair(ParentDir, InferredDirectory())).first;
607 }
608
609 if (inferred->second.InferModules) {
610 // We're allowed to infer for this directory, but make sure it's okay
611 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000612 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000613 canInfer = std::find(inferred->second.ExcludedModules.begin(),
614 inferred->second.ExcludedModules.end(),
615 Name) == inferred->second.ExcludedModules.end();
616
617 if (inferred->second.InferSystemModules)
618 IsSystem = true;
619 }
620 }
621 }
622
623 // If we're not allowed to infer a framework module, don't.
624 if (!canInfer)
625 return 0;
626 }
627
628
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000629 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000630 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramerceb6dc82013-06-28 16:25:46 +0000631 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000632 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000633
634 // FIXME: If there's no umbrella header, we could probably scan the
635 // framework to load *everything*. But, it's not clear that this is a good
636 // idea.
637 if (!UmbrellaHeader)
638 return 0;
639
Douglas Gregorac252a32011-12-06 19:39:29 +0000640 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
641 /*IsFramework=*/true, /*IsExplicit=*/false);
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000642 if (LangOpts.CurrentModule == ModuleName) {
643 SourceModule = Result;
644 SourceModuleName = ModuleName;
645 }
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000646 if (IsSystem)
647 Result->IsSystem = IsSystem;
648
Douglas Gregorb7a78192012-01-04 23:32:19 +0000649 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000650 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000651
Douglas Gregor489ad432011-12-08 18:00:48 +0000652 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000653 Result->Umbrella = UmbrellaHeader;
Daniel Jasperc6417092013-10-22 08:09:47 +0000654 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000655 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000656
657 // export *
658 Result->Exports.push_back(Module::ExportDecl(0, true));
659
Douglas Gregore209e502011-12-06 01:10:29 +0000660 // module * { export * }
661 Result->InferSubmodules = true;
662 Result->InferExportWildcard = true;
663
Douglas Gregorac252a32011-12-06 19:39:29 +0000664 // Look for subframeworks.
665 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000666 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000667 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000668 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer0f599ac2013-09-11 11:23:15 +0000669 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000670 for (llvm::sys::fs::directory_iterator
Benjamin Kramer0f599ac2013-09-11 11:23:15 +0000671 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000672 Dir != DirEnd && !EC; Dir.increment(EC)) {
673 if (!StringRef(Dir->path()).endswith(".framework"))
674 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000675
Douglas Gregorac252a32011-12-06 19:39:29 +0000676 if (const DirectoryEntry *SubframeworkDir
677 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000678 // Note: as an egregious but useful hack, we use the real path here and
679 // check whether it is actually a subdirectory of the parent directory.
680 // This will not be the case if the 'subframework' is actually a symlink
681 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000682 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
683 bool FoundParent = false;
684 do {
685 // Get the parent directory name.
686 SubframeworkDirName
687 = llvm::sys::path::parent_path(SubframeworkDirName);
688 if (SubframeworkDirName.empty())
689 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000690
Douglas Gregor713b7c02013-01-26 00:55:12 +0000691 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
692 FoundParent = true;
693 break;
694 }
695 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000696
Douglas Gregor713b7c02013-01-26 00:55:12 +0000697 if (!FoundParent)
698 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000699
Douglas Gregorac252a32011-12-06 19:39:29 +0000700 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000701 SmallString<32> NameBuf;
702 inferFrameworkModule(sanitizeFilenameAsIdentifier(
703 llvm::sys::path::stem(Dir->path()), NameBuf),
704 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000705 }
706 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000707
Douglas Gregor8767dc22013-01-14 17:57:51 +0000708 // If the module is a top-level framework, automatically link against the
709 // framework.
710 if (!Result->isSubFramework()) {
711 inferFrameworkLink(Result, FrameworkDir, FileMgr);
712 }
713
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000714 return Result;
715}
716
Douglas Gregore209e502011-12-06 01:10:29 +0000717void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasperc6417092013-10-22 08:09:47 +0000718 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor10694ce2011-12-08 17:39:04 +0000719 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000720 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000721}
722
Douglas Gregor77d029f2011-12-08 19:11:24 +0000723void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
724 Mod->Umbrella = UmbrellaDir;
725 UmbrellaDirs[UmbrellaDir] = Mod;
726}
727
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000728void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000729 ModuleHeaderRole Role) {
730 if (Role == ExcludedHeader) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000731 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000732 } else {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000733 if (Role == PrivateHeader)
734 Mod->PrivateHeaders.push_back(Header);
735 else
736 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000737 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000738 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000739 }
Daniel Jasperc6417092013-10-22 08:09:47 +0000740 Headers[Header].push_back(KnownHeader(Mod, Role));
Douglas Gregore209e502011-12-06 01:10:29 +0000741}
742
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000743const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000744ModuleMap::getContainingModuleMapFile(Module *Module) const {
Manuel Klimekee0cd372013-10-24 07:51:24 +0000745 if (Module->DefinitionLoc.isInvalid())
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000746 return 0;
747
Manuel Klimekee0cd372013-10-24 07:51:24 +0000748 return SourceMgr.getFileEntryForID(
749 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000750}
751
Douglas Gregora30cfe52011-11-11 19:10:28 +0000752void ModuleMap::dump() {
753 llvm::errs() << "Modules:";
754 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
755 MEnd = Modules.end();
756 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000757 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000758
759 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000760 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000761 H != HEnd; ++H) {
Daniel Jasperc6417092013-10-22 08:09:47 +0000762 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
763 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
764 E = H->second.end();
765 I != E; ++I) {
766 if (I != H->second.begin())
767 llvm::errs() << ",";
768 llvm::errs() << I->getModule()->getFullModuleName();
769 }
770 llvm::errs() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000771 }
772}
773
Douglas Gregor90db2602011-12-02 01:47:07 +0000774bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
775 bool HadError = false;
776 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
777 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
778 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000779 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000780 Mod->Exports.push_back(Export);
781 else
782 HadError = true;
783 }
784 Mod->UnresolvedExports.clear();
785 return HadError;
786}
787
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000788bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
789 bool HadError = false;
790 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
791 Module *DirectUse =
792 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
793 if (DirectUse)
794 Mod->DirectUses.push_back(DirectUse);
795 else
796 HadError = true;
797 }
798 Mod->UnresolvedDirectUses.clear();
799 return HadError;
800}
801
Douglas Gregor906d66a2013-03-20 21:10:35 +0000802bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
803 bool HadError = false;
804 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
805 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
806 Mod, Complain);
807 if (!OtherMod) {
808 HadError = true;
809 continue;
810 }
811
812 Module::Conflict Conflict;
813 Conflict.Other = OtherMod;
814 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
815 Mod->Conflicts.push_back(Conflict);
816 }
817 Mod->UnresolvedConflicts.clear();
818 return HadError;
819}
820
Douglas Gregor55988682011-12-05 16:33:54 +0000821Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
822 if (Loc.isInvalid())
823 return 0;
824
825 // Use the expansion location to determine which module we're in.
826 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
827 if (!ExpansionLoc.isFileID())
828 return 0;
829
830
831 const SourceManager &SrcMgr = Loc.getManager();
832 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000833
Douglas Gregor303aae92012-01-06 17:19:32 +0000834 while (const FileEntry *ExpansionFile
835 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
836 // Find the module that owns this header (if any).
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000837 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor303aae92012-01-06 17:19:32 +0000838 return Mod;
839
840 // No module owns this header, so look up the inclusion chain to see if
841 // any included header has an associated module.
842 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
843 if (IncludeLoc.isInvalid())
844 return 0;
845
846 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
847 }
848
849 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000850}
851
Douglas Gregora30cfe52011-11-11 19:10:28 +0000852//----------------------------------------------------------------------------//
853// Module map file parser
854//----------------------------------------------------------------------------//
855
856namespace clang {
857 /// \brief A token in a module map file.
858 struct MMToken {
859 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000860 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000861 ConfigMacros,
Douglas Gregor906d66a2013-03-20 21:10:35 +0000862 Conflict,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000863 EndOfFile,
864 HeaderKeyword,
865 Identifier,
Richard Smith5794b532013-10-28 22:18:19 +0000866 Exclaim,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000867 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000868 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000869 ExportKeyword,
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000870 ExternKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000871 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000872 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000873 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000874 Period,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000875 PrivateKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000876 UmbrellaKeyword,
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000877 UseKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000878 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000879 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000880 StringLiteral,
881 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000882 RBrace,
883 LSquare,
884 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000885 } Kind;
886
887 unsigned Location;
888 unsigned StringLength;
889 const char *StringData;
890
891 void clear() {
892 Kind = EndOfFile;
893 Location = 0;
894 StringLength = 0;
895 StringData = 0;
896 }
897
898 bool is(TokenKind K) const { return Kind == K; }
899
900 SourceLocation getLocation() const {
901 return SourceLocation::getFromRawEncoding(Location);
902 }
903
904 StringRef getString() const {
905 return StringRef(StringData, StringLength);
906 }
907 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000908
909 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000910 struct Attributes {
Stephen Hines651f13c2014-04-23 16:59:28 -0700911 Attributes() : IsSystem(), IsExternC(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000912
913 /// \brief Whether this is a system module.
914 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000915
Stephen Hines651f13c2014-04-23 16:59:28 -0700916 /// \brief Whether this is an extern "C" module.
917 unsigned IsExternC : 1;
918
Douglas Gregor63a72682013-03-20 00:22:05 +0000919 /// \brief Whether this is an exhaustive set of configuration macros.
920 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000921 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000922
Douglas Gregor82e52372012-11-06 19:39:40 +0000923
Douglas Gregora30cfe52011-11-11 19:10:28 +0000924 class ModuleMapParser {
925 Lexer &L;
926 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000927
928 /// \brief Default target information, used only for string literal
929 /// parsing.
930 const TargetInfo *Target;
931
Douglas Gregora30cfe52011-11-11 19:10:28 +0000932 DiagnosticsEngine &Diags;
933 ModuleMap &Map;
934
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000935 /// \brief The directory that this module map resides in.
936 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000937
938 /// \brief The directory containing Clang-supplied headers.
939 const DirectoryEntry *BuiltinIncludeDir;
940
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000941 /// \brief Whether this module map is in a system header directory.
942 bool IsSystem;
943
Douglas Gregora30cfe52011-11-11 19:10:28 +0000944 /// \brief Whether an error occurred.
945 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000946
Douglas Gregora30cfe52011-11-11 19:10:28 +0000947 /// \brief Stores string data for the various string literals referenced
948 /// during parsing.
949 llvm::BumpPtrAllocator StringData;
950
951 /// \brief The current token.
952 MMToken Tok;
953
954 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000955 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000956
957 /// \brief Consume the current token and return its location.
958 SourceLocation consumeToken();
959
960 /// \brief Skip tokens until we reach the a token with the given kind
961 /// (or the end of the file).
962 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000963
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000964 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000965 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000966 void parseModuleDecl();
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000967 void parseExternModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000968 void parseRequiresDecl();
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000969 void parseHeaderDecl(clang::MMToken::TokenKind,
970 SourceLocation LeadingLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000971 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000972 void parseExportDecl();
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000973 void parseUseDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000974 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000975 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000976 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000977 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000978 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000979
Douglas Gregor6a1db482011-12-09 02:04:43 +0000980 const DirectoryEntry *getOverriddenHeaderSearchDir();
981
Douglas Gregora30cfe52011-11-11 19:10:28 +0000982 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000983 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000984 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000985 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000986 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000987 const DirectoryEntry *Directory,
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000988 const DirectoryEntry *BuiltinIncludeDir,
989 bool IsSystem)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000990 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000991 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
992 IsSystem(IsSystem), HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000993 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000994 Tok.clear();
995 consumeToken();
996 }
997
998 bool parseModuleMapFile();
999 };
1000}
1001
1002SourceLocation ModuleMapParser::consumeToken() {
1003retry:
1004 SourceLocation Result = Tok.getLocation();
1005 Tok.clear();
1006
1007 Token LToken;
1008 L.LexFromRawLexer(LToken);
1009 Tok.Location = LToken.getLocation().getRawEncoding();
1010 switch (LToken.getKind()) {
1011 case tok::raw_identifier:
1012 Tok.StringData = LToken.getRawIdentifierData();
1013 Tok.StringLength = LToken.getLength();
1014 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001015 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +00001016 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001017 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +00001018 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +00001019 .Case("export", MMToken::ExportKeyword)
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001020 .Case("extern", MMToken::ExternKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +00001021 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +00001022 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001023 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +00001024 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001025 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +00001026 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +00001027 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001028 .Case("use", MMToken::UseKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +00001029 .Default(MMToken::Identifier);
1030 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +00001031
1032 case tok::comma:
1033 Tok.Kind = MMToken::Comma;
1034 break;
1035
Douglas Gregora30cfe52011-11-11 19:10:28 +00001036 case tok::eof:
1037 Tok.Kind = MMToken::EndOfFile;
1038 break;
1039
1040 case tok::l_brace:
1041 Tok.Kind = MMToken::LBrace;
1042 break;
1043
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001044 case tok::l_square:
1045 Tok.Kind = MMToken::LSquare;
1046 break;
1047
Douglas Gregor90db2602011-12-02 01:47:07 +00001048 case tok::period:
1049 Tok.Kind = MMToken::Period;
1050 break;
1051
Douglas Gregora30cfe52011-11-11 19:10:28 +00001052 case tok::r_brace:
1053 Tok.Kind = MMToken::RBrace;
1054 break;
1055
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001056 case tok::r_square:
1057 Tok.Kind = MMToken::RSquare;
1058 break;
1059
Douglas Gregor90db2602011-12-02 01:47:07 +00001060 case tok::star:
1061 Tok.Kind = MMToken::Star;
1062 break;
1063
Richard Smith5794b532013-10-28 22:18:19 +00001064 case tok::exclaim:
1065 Tok.Kind = MMToken::Exclaim;
1066 break;
1067
Douglas Gregora30cfe52011-11-11 19:10:28 +00001068 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +00001069 if (LToken.hasUDSuffix()) {
1070 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1071 HadError = true;
1072 goto retry;
1073 }
1074
Douglas Gregora30cfe52011-11-11 19:10:28 +00001075 // Parse the string literal.
1076 LangOptions LangOpts;
1077 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
1078 if (StringLiteral.hadError)
1079 goto retry;
1080
1081 // Copy the string literal into our string data allocator.
1082 unsigned Length = StringLiteral.GetStringLength();
1083 char *Saved = StringData.Allocate<char>(Length + 1);
1084 memcpy(Saved, StringLiteral.GetString().data(), Length);
1085 Saved[Length] = 0;
1086
1087 // Form the token.
1088 Tok.Kind = MMToken::StringLiteral;
1089 Tok.StringData = Saved;
1090 Tok.StringLength = Length;
1091 break;
1092 }
1093
1094 case tok::comment:
1095 goto retry;
1096
1097 default:
1098 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1099 HadError = true;
1100 goto retry;
1101 }
1102
1103 return Result;
1104}
1105
1106void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1107 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001108 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001109 do {
1110 switch (Tok.Kind) {
1111 case MMToken::EndOfFile:
1112 return;
1113
1114 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001115 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +00001116 return;
1117
1118 ++braceDepth;
1119 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001120
1121 case MMToken::LSquare:
1122 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1123 return;
1124
1125 ++squareDepth;
1126 break;
1127
Douglas Gregora30cfe52011-11-11 19:10:28 +00001128 case MMToken::RBrace:
1129 if (braceDepth > 0)
1130 --braceDepth;
1131 else if (Tok.is(K))
1132 return;
1133 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001134
1135 case MMToken::RSquare:
1136 if (squareDepth > 0)
1137 --squareDepth;
1138 else if (Tok.is(K))
1139 return;
1140 break;
1141
Douglas Gregora30cfe52011-11-11 19:10:28 +00001142 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001143 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +00001144 return;
1145 break;
1146 }
1147
1148 consumeToken();
1149 } while (true);
1150}
1151
Douglas Gregor587986e2011-12-07 02:23:45 +00001152/// \brief Parse a module-id.
1153///
1154/// module-id:
1155/// identifier
1156/// identifier '.' module-id
1157///
1158/// \returns true if an error occurred, false otherwise.
1159bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1160 Id.clear();
1161 do {
Stephen Hines651f13c2014-04-23 16:59:28 -07001162 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001163 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1164 consumeToken();
1165 } else {
1166 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1167 return true;
1168 }
1169
1170 if (!Tok.is(MMToken::Period))
1171 break;
1172
1173 consumeToken();
1174 } while (true);
1175
1176 return false;
1177}
1178
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001179namespace {
1180 /// \brief Enumerates the known attributes.
1181 enum AttributeKind {
1182 /// \brief An unknown attribute.
1183 AT_unknown,
1184 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001185 AT_system,
Stephen Hines651f13c2014-04-23 16:59:28 -07001186 /// \brief The 'extern_c' attribute.
1187 AT_extern_c,
Douglas Gregor63a72682013-03-20 00:22:05 +00001188 /// \brief The 'exhaustive' attribute.
1189 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001190 };
1191}
1192
Douglas Gregora30cfe52011-11-11 19:10:28 +00001193/// \brief Parse a module declaration.
1194///
1195/// module-declaration:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001196/// 'extern' 'module' module-id string-literal
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001197/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1198/// { module-member* }
1199///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001200/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001201/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001202/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001203/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001204/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001205/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001206///
1207/// submodule-declaration:
1208/// module-declaration
1209/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001210void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001211 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001212 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1213 if (Tok.is(MMToken::ExternKeyword)) {
1214 parseExternModuleDecl();
1215 return;
1216 }
1217
Douglas Gregord620a842011-12-06 17:16:41 +00001218 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001219 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001220 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001221 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001222
Douglas Gregord620a842011-12-06 17:16:41 +00001223 // Parse 'explicit' keyword, if present.
1224 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001225 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001226 Explicit = true;
1227 }
1228
1229 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001230 if (Tok.is(MMToken::FrameworkKeyword)) {
1231 consumeToken();
1232 Framework = true;
1233 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001234
1235 // Parse 'module' keyword.
1236 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001237 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001238 consumeToken();
1239 HadError = true;
1240 return;
1241 }
1242 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001243
1244 // If we have a wildcard for the module name, this is an inferred submodule.
1245 // Parse it.
1246 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001247 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001248
1249 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001250 ModuleId Id;
1251 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001252 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001253 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001254 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001255
Douglas Gregor587986e2011-12-07 02:23:45 +00001256 if (ActiveModule) {
1257 if (Id.size() > 1) {
1258 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1259 << SourceRange(Id.front().second, Id.back().second);
1260
1261 HadError = true;
1262 return;
1263 }
1264 } else if (Id.size() == 1 && Explicit) {
1265 // Top-level modules can't be explicit.
1266 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1267 Explicit = false;
1268 ExplicitLoc = SourceLocation();
1269 HadError = true;
1270 }
1271
1272 Module *PreviousActiveModule = ActiveModule;
1273 if (Id.size() > 1) {
1274 // This module map defines a submodule. Go find the module of which it
1275 // is a submodule.
1276 ActiveModule = 0;
1277 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1278 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1279 ActiveModule = Next;
1280 continue;
1281 }
1282
1283 if (ActiveModule) {
1284 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Stephen Hines651f13c2014-04-23 16:59:28 -07001285 << Id[I].first
1286 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001287 } else {
1288 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1289 }
1290 HadError = true;
1291 return;
1292 }
1293 }
1294
1295 StringRef ModuleName = Id.back().first;
1296 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001297
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001298 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001299 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001300 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001301
Douglas Gregora30cfe52011-11-11 19:10:28 +00001302 // Parse the opening brace.
1303 if (!Tok.is(MMToken::LBrace)) {
1304 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1305 << ModuleName;
1306 HadError = true;
1307 return;
1308 }
1309 SourceLocation LBraceLoc = consumeToken();
1310
1311 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001312 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001313 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1314 // Skip the module definition.
1315 skipUntil(MMToken::RBrace);
1316 if (Tok.is(MMToken::RBrace))
1317 consumeToken();
1318 else {
1319 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1320 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1321 HadError = true;
1322 }
1323 return;
1324 }
1325
Douglas Gregora30cfe52011-11-11 19:10:28 +00001326 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1327 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001328 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001329
1330 // Skip the module definition.
1331 skipUntil(MMToken::RBrace);
1332 if (Tok.is(MMToken::RBrace))
1333 consumeToken();
1334
1335 HadError = true;
1336 return;
1337 }
1338
1339 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001340 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1341 Explicit).first;
1342 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001343 if (Attrs.IsSystem || IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001344 ActiveModule->IsSystem = true;
Stephen Hines651f13c2014-04-23 16:59:28 -07001345 if (Attrs.IsExternC)
1346 ActiveModule->IsExternC = true;
1347
Douglas Gregora30cfe52011-11-11 19:10:28 +00001348 bool Done = false;
1349 do {
1350 switch (Tok.Kind) {
1351 case MMToken::EndOfFile:
1352 case MMToken::RBrace:
1353 Done = true;
1354 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001355
1356 case MMToken::ConfigMacros:
1357 parseConfigMacros();
1358 break;
1359
Douglas Gregor906d66a2013-03-20 21:10:35 +00001360 case MMToken::Conflict:
1361 parseConflict();
1362 break;
1363
Douglas Gregora30cfe52011-11-11 19:10:28 +00001364 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001365 case MMToken::ExternKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001366 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001367 case MMToken::ModuleKeyword:
1368 parseModuleDecl();
1369 break;
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001370
Douglas Gregor90db2602011-12-02 01:47:07 +00001371 case MMToken::ExportKeyword:
1372 parseExportDecl();
1373 break;
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001374
1375 case MMToken::UseKeyword:
1376 parseUseDecl();
1377 break;
Douglas Gregor90db2602011-12-02 01:47:07 +00001378
Douglas Gregor51f564f2011-12-31 04:05:44 +00001379 case MMToken::RequiresKeyword:
1380 parseRequiresDecl();
1381 break;
1382
Douglas Gregor77d029f2011-12-08 19:11:24 +00001383 case MMToken::UmbrellaKeyword: {
1384 SourceLocation UmbrellaLoc = consumeToken();
1385 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001386 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +00001387 else
1388 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001389 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001390 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001391
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001392 case MMToken::ExcludeKeyword: {
1393 SourceLocation ExcludeLoc = consumeToken();
1394 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001395 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001396 } else {
1397 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1398 << "exclude";
1399 }
1400 break;
1401 }
1402
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001403 case MMToken::PrivateKeyword: {
1404 SourceLocation PrivateLoc = consumeToken();
1405 if (Tok.is(MMToken::HeaderKeyword)) {
1406 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1407 } else {
1408 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1409 << "private";
1410 }
1411 break;
1412 }
1413
Douglas Gregor489ad432011-12-08 18:00:48 +00001414 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001415 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001416 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001417
1418 case MMToken::LinkKeyword:
1419 parseLinkDecl();
1420 break;
1421
Douglas Gregora30cfe52011-11-11 19:10:28 +00001422 default:
1423 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1424 consumeToken();
1425 break;
1426 }
1427 } while (!Done);
1428
1429 if (Tok.is(MMToken::RBrace))
1430 consumeToken();
1431 else {
1432 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1433 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1434 HadError = true;
1435 }
1436
Douglas Gregor8767dc22013-01-14 17:57:51 +00001437 // If the active module is a top-level framework, and there are no link
1438 // libraries, automatically link against the framework.
1439 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1440 ActiveModule->LinkLibraries.empty()) {
1441 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1442 }
1443
Douglas Gregor587986e2011-12-07 02:23:45 +00001444 // We're done parsing this module. Pop back to the previous module.
1445 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001446}
Douglas Gregord620a842011-12-06 17:16:41 +00001447
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001448/// \brief Parse an extern module declaration.
1449///
1450/// extern module-declaration:
1451/// 'extern' 'module' module-id string-literal
1452void ModuleMapParser::parseExternModuleDecl() {
1453 assert(Tok.is(MMToken::ExternKeyword));
1454 consumeToken(); // 'extern' keyword
1455
1456 // Parse 'module' keyword.
1457 if (!Tok.is(MMToken::ModuleKeyword)) {
1458 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1459 consumeToken();
1460 HadError = true;
1461 return;
1462 }
1463 consumeToken(); // 'module' keyword
1464
1465 // Parse the module name.
1466 ModuleId Id;
1467 if (parseModuleId(Id)) {
1468 HadError = true;
1469 return;
1470 }
1471
1472 // Parse the referenced module map file name.
1473 if (!Tok.is(MMToken::StringLiteral)) {
1474 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1475 HadError = true;
1476 return;
1477 }
1478 std::string FileName = Tok.getString();
1479 consumeToken(); // filename
1480
1481 StringRef FileNameRef = FileName;
1482 SmallString<128> ModuleMapFileName;
1483 if (llvm::sys::path::is_relative(FileNameRef)) {
1484 ModuleMapFileName += Directory->getName();
1485 llvm::sys::path::append(ModuleMapFileName, FileName);
1486 FileNameRef = ModuleMapFileName.str();
1487 }
1488 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1489 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1490}
1491
Douglas Gregor51f564f2011-12-31 04:05:44 +00001492/// \brief Parse a requires declaration.
1493///
1494/// requires-declaration:
1495/// 'requires' feature-list
1496///
1497/// feature-list:
Richard Smith5794b532013-10-28 22:18:19 +00001498/// feature ',' feature-list
1499/// feature
1500///
1501/// feature:
1502/// '!'[opt] identifier
Douglas Gregor51f564f2011-12-31 04:05:44 +00001503void ModuleMapParser::parseRequiresDecl() {
1504 assert(Tok.is(MMToken::RequiresKeyword));
1505
1506 // Parse 'requires' keyword.
1507 consumeToken();
1508
1509 // Parse the feature-list.
1510 do {
Richard Smith5794b532013-10-28 22:18:19 +00001511 bool RequiredState = true;
1512 if (Tok.is(MMToken::Exclaim)) {
1513 RequiredState = false;
1514 consumeToken();
1515 }
1516
Douglas Gregor51f564f2011-12-31 04:05:44 +00001517 if (!Tok.is(MMToken::Identifier)) {
1518 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1519 HadError = true;
1520 return;
1521 }
1522
1523 // Consume the feature name.
1524 std::string Feature = Tok.getString();
1525 consumeToken();
1526
1527 // Add this feature.
Richard Smith5794b532013-10-28 22:18:19 +00001528 ActiveModule->addRequirement(Feature, RequiredState,
1529 Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001530
1531 if (!Tok.is(MMToken::Comma))
1532 break;
1533
1534 // Consume the comma.
1535 consumeToken();
1536 } while (true);
1537}
1538
Douglas Gregord620a842011-12-06 17:16:41 +00001539/// \brief Append to \p Paths the set of paths needed to get to the
1540/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001541static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001542 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001543 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001544 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001545 for (; Mod; Mod = Mod->Parent) {
1546 if (Mod->IsFramework)
1547 Paths.push_back(Mod->Name);
1548 }
1549
1550 if (Paths.empty())
1551 return;
1552
1553 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001554 for (unsigned I = Paths.size() - 1; I != 0; --I)
1555 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregord620a842011-12-06 17:16:41 +00001556}
1557
Douglas Gregora30cfe52011-11-11 19:10:28 +00001558/// \brief Parse a header declaration.
1559///
1560/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001561/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001562/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001563void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1564 SourceLocation LeadingLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001565 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001566 consumeToken();
1567
Douglas Gregora30cfe52011-11-11 19:10:28 +00001568 // Parse the header name.
1569 if (!Tok.is(MMToken::StringLiteral)) {
1570 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1571 << "header";
1572 HadError = true;
1573 return;
1574 }
Stephen Hines651f13c2014-04-23 16:59:28 -07001575 Module::HeaderDirective Header;
1576 Header.FileName = Tok.getString();
1577 Header.FileNameLoc = consumeToken();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001578
Douglas Gregor77d029f2011-12-08 19:11:24 +00001579 // Check whether we already have an umbrella.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001580 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Stephen Hines651f13c2014-04-23 16:59:28 -07001581 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001582 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001583 HadError = true;
1584 return;
1585 }
1586
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001587 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001588 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001589 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001590 SmallString<128> PathName;
Stephen Hines651f13c2014-04-23 16:59:28 -07001591 if (llvm::sys::path::is_absolute(Header.FileName)) {
1592 PathName = Header.FileName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001593 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001594 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1595 PathName = Dir->getName();
Stephen Hines651f13c2014-04-23 16:59:28 -07001596 llvm::sys::path::append(PathName, Header.FileName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001597 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001598 } else {
1599 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001600 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001601 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001602
Douglas Gregord620a842011-12-06 17:16:41 +00001603 if (ActiveModule->isPartOfFramework()) {
1604 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001605
1606 // Check whether this file is in the public headers.
Stephen Hines651f13c2014-04-23 16:59:28 -07001607 llvm::sys::path::append(PathName, "Headers", Header.FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001608 File = SourceMgr.getFileManager().getFile(PathName);
1609
1610 if (!File) {
1611 // Check whether this file is in the private headers.
1612 PathName.resize(PathLength);
Stephen Hines651f13c2014-04-23 16:59:28 -07001613 llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001614 File = SourceMgr.getFileManager().getFile(PathName);
1615 }
1616 } else {
1617 // Lookup for normal headers.
Stephen Hines651f13c2014-04-23 16:59:28 -07001618 llvm::sys::path::append(PathName, Header.FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001619 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001620
1621 // If this is a system module with a top-level header, this header
1622 // may have a counterpart (or replacement) in the set of headers
1623 // supplied by Clang. Find that builtin header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001624 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1625 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Stephen Hines651f13c2014-04-23 16:59:28 -07001626 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001627 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Stephen Hines651f13c2014-04-23 16:59:28 -07001628 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001629 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1630
1631 // If Clang supplies this header but the underlying system does not,
1632 // just silently swap in our builtin version. Otherwise, we'll end
1633 // up adding both (later).
1634 if (!File && BuiltinFile) {
1635 File = BuiltinFile;
1636 BuiltinFile = 0;
1637 }
1638 }
Douglas Gregord620a842011-12-06 17:16:41 +00001639 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001640 }
Douglas Gregora8654052011-11-17 22:09:43 +00001641
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001642 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1643 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001644 if (File) {
Daniel Jasperc6417092013-10-22 08:09:47 +00001645 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001646 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001647 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001648 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001649 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001650 HadError = true;
1651 } else {
1652 // Record this umbrella header.
1653 Map.setUmbrellaHeader(ActiveModule, File);
1654 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001655 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001656 // Record this header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001657 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1658 if (LeadingToken == MMToken::ExcludeKeyword)
1659 Role = ModuleMap::ExcludedHeader;
1660 else if (LeadingToken == MMToken::PrivateKeyword)
1661 Role = ModuleMap::PrivateHeader;
1662 else
1663 assert(LeadingToken == MMToken::HeaderKeyword);
1664
1665 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001666
1667 // If there is a builtin counterpart to this file, add it now.
1668 if (BuiltinFile)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001669 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001670 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001671 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor71f49f52012-11-15 19:47:16 +00001672 // Ignore excluded header files. They're optional anyway.
Stephen Hines651f13c2014-04-23 16:59:28 -07001673
1674 // If we find a module that has a missing header, we mark this module as
1675 // unavailable and store the header directive for displaying diagnostics.
1676 // Other submodules in the same module can still be used.
1677 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
1678 ActiveModule->IsAvailable = false;
1679 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001680 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001681}
1682
Douglas Gregor77d029f2011-12-08 19:11:24 +00001683/// \brief Parse an umbrella directory declaration.
1684///
1685/// umbrella-dir-declaration:
1686/// umbrella string-literal
1687void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1688 // Parse the directory name.
1689 if (!Tok.is(MMToken::StringLiteral)) {
1690 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1691 << "umbrella";
1692 HadError = true;
1693 return;
1694 }
1695
1696 std::string DirName = Tok.getString();
1697 SourceLocation DirNameLoc = consumeToken();
1698
1699 // Check whether we already have an umbrella.
1700 if (ActiveModule->Umbrella) {
1701 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1702 << ActiveModule->getFullModuleName();
1703 HadError = true;
1704 return;
1705 }
1706
1707 // Look for this file.
1708 const DirectoryEntry *Dir = 0;
1709 if (llvm::sys::path::is_absolute(DirName))
1710 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1711 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001712 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001713 PathName = Directory->getName();
1714 llvm::sys::path::append(PathName, DirName);
1715 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1716 }
1717
1718 if (!Dir) {
1719 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1720 << DirName;
1721 HadError = true;
1722 return;
1723 }
1724
1725 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1726 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1727 << OwningModule->getFullModuleName();
1728 HadError = true;
1729 return;
1730 }
1731
1732 // Record this umbrella directory.
1733 Map.setUmbrellaDir(ActiveModule, Dir);
1734}
1735
Douglas Gregor90db2602011-12-02 01:47:07 +00001736/// \brief Parse a module export declaration.
1737///
1738/// export-declaration:
1739/// 'export' wildcard-module-id
1740///
1741/// wildcard-module-id:
1742/// identifier
1743/// '*'
1744/// identifier '.' wildcard-module-id
1745void ModuleMapParser::parseExportDecl() {
1746 assert(Tok.is(MMToken::ExportKeyword));
1747 SourceLocation ExportLoc = consumeToken();
1748
1749 // Parse the module-id with an optional wildcard at the end.
1750 ModuleId ParsedModuleId;
1751 bool Wildcard = false;
1752 do {
1753 if (Tok.is(MMToken::Identifier)) {
1754 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1755 Tok.getLocation()));
1756 consumeToken();
1757
1758 if (Tok.is(MMToken::Period)) {
1759 consumeToken();
1760 continue;
1761 }
1762
1763 break;
1764 }
1765
1766 if(Tok.is(MMToken::Star)) {
1767 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001768 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001769 break;
1770 }
1771
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001772 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor90db2602011-12-02 01:47:07 +00001773 HadError = true;
1774 return;
1775 } while (true);
1776
1777 Module::UnresolvedExportDecl Unresolved = {
1778 ExportLoc, ParsedModuleId, Wildcard
1779 };
1780 ActiveModule->UnresolvedExports.push_back(Unresolved);
1781}
1782
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001783/// \brief Parse a module uses declaration.
1784///
1785/// uses-declaration:
1786/// 'uses' wildcard-module-id
1787void ModuleMapParser::parseUseDecl() {
1788 assert(Tok.is(MMToken::UseKeyword));
1789 consumeToken();
1790 // Parse the module-id.
1791 ModuleId ParsedModuleId;
Stephen Hines651f13c2014-04-23 16:59:28 -07001792 parseModuleId(ParsedModuleId);
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001793
1794 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1795}
1796
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001797/// \brief Parse a link declaration.
1798///
1799/// module-declaration:
1800/// 'link' 'framework'[opt] string-literal
1801void ModuleMapParser::parseLinkDecl() {
1802 assert(Tok.is(MMToken::LinkKeyword));
1803 SourceLocation LinkLoc = consumeToken();
1804
1805 // Parse the optional 'framework' keyword.
1806 bool IsFramework = false;
1807 if (Tok.is(MMToken::FrameworkKeyword)) {
1808 consumeToken();
1809 IsFramework = true;
1810 }
1811
1812 // Parse the library name
1813 if (!Tok.is(MMToken::StringLiteral)) {
1814 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1815 << IsFramework << SourceRange(LinkLoc);
1816 HadError = true;
1817 return;
1818 }
1819
1820 std::string LibraryName = Tok.getString();
1821 consumeToken();
1822 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1823 IsFramework));
1824}
1825
Douglas Gregor63a72682013-03-20 00:22:05 +00001826/// \brief Parse a configuration macro declaration.
1827///
1828/// module-declaration:
1829/// 'config_macros' attributes[opt] config-macro-list?
1830///
1831/// config-macro-list:
1832/// identifier (',' identifier)?
1833void ModuleMapParser::parseConfigMacros() {
1834 assert(Tok.is(MMToken::ConfigMacros));
1835 SourceLocation ConfigMacrosLoc = consumeToken();
1836
1837 // Only top-level modules can have configuration macros.
1838 if (ActiveModule->Parent) {
1839 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1840 }
1841
1842 // Parse the optional attributes.
1843 Attributes Attrs;
1844 parseOptionalAttributes(Attrs);
1845 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1846 ActiveModule->ConfigMacrosExhaustive = true;
1847 }
1848
1849 // If we don't have an identifier, we're done.
1850 if (!Tok.is(MMToken::Identifier))
1851 return;
1852
1853 // Consume the first identifier.
1854 if (!ActiveModule->Parent) {
1855 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1856 }
1857 consumeToken();
1858
1859 do {
1860 // If there's a comma, consume it.
1861 if (!Tok.is(MMToken::Comma))
1862 break;
1863 consumeToken();
1864
1865 // We expect to see a macro name here.
1866 if (!Tok.is(MMToken::Identifier)) {
1867 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1868 break;
1869 }
1870
1871 // Consume the macro name.
1872 if (!ActiveModule->Parent) {
1873 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1874 }
1875 consumeToken();
1876 } while (true);
1877}
1878
Douglas Gregor906d66a2013-03-20 21:10:35 +00001879/// \brief Format a module-id into a string.
1880static std::string formatModuleId(const ModuleId &Id) {
1881 std::string result;
1882 {
1883 llvm::raw_string_ostream OS(result);
1884
1885 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1886 if (I)
1887 OS << ".";
1888 OS << Id[I].first;
1889 }
1890 }
1891
1892 return result;
1893}
1894
1895/// \brief Parse a conflict declaration.
1896///
1897/// module-declaration:
1898/// 'conflict' module-id ',' string-literal
1899void ModuleMapParser::parseConflict() {
1900 assert(Tok.is(MMToken::Conflict));
1901 SourceLocation ConflictLoc = consumeToken();
1902 Module::UnresolvedConflict Conflict;
1903
1904 // Parse the module-id.
1905 if (parseModuleId(Conflict.Id))
1906 return;
1907
1908 // Parse the ','.
1909 if (!Tok.is(MMToken::Comma)) {
1910 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1911 << SourceRange(ConflictLoc);
1912 return;
1913 }
1914 consumeToken();
1915
1916 // Parse the message.
1917 if (!Tok.is(MMToken::StringLiteral)) {
1918 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1919 << formatModuleId(Conflict.Id);
1920 return;
1921 }
1922 Conflict.Message = Tok.getString().str();
1923 consumeToken();
1924
1925 // Add this unresolved conflict.
1926 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1927}
1928
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001929/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001930///
1931/// module-declaration:
1932/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1933/// { inferred-module-member* }
1934///
1935/// inferred-module-member:
1936/// 'export' '*'
1937/// 'exclude' identifier
1938void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001939 assert(Tok.is(MMToken::Star));
1940 SourceLocation StarLoc = consumeToken();
1941 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001942
Douglas Gregor1e123682011-12-05 22:27:44 +00001943 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001944 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001945 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1946 Failed = true;
1947 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001948
1949 if (ActiveModule) {
1950 // Inferred modules must have umbrella directories.
1951 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1952 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1953 Failed = true;
1954 }
1955
1956 // Check for redefinition of an inferred module.
1957 if (!Failed && ActiveModule->InferSubmodules) {
1958 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1959 if (ActiveModule->InferredSubmoduleLoc.isValid())
1960 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1961 diag::note_mmap_prev_definition);
1962 Failed = true;
1963 }
1964
1965 // Check for the 'framework' keyword, which is not permitted here.
1966 if (Framework) {
1967 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1968 Framework = false;
1969 }
1970 } else if (Explicit) {
1971 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1972 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001973 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001974
Douglas Gregor1e123682011-12-05 22:27:44 +00001975 // If there were any problems with this inferred submodule, skip its body.
1976 if (Failed) {
1977 if (Tok.is(MMToken::LBrace)) {
1978 consumeToken();
1979 skipUntil(MMToken::RBrace);
1980 if (Tok.is(MMToken::RBrace))
1981 consumeToken();
1982 }
1983 HadError = true;
1984 return;
1985 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001986
1987 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001988 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001989 parseOptionalAttributes(Attrs);
1990
1991 if (ActiveModule) {
1992 // Note that we have an inferred submodule.
1993 ActiveModule->InferSubmodules = true;
1994 ActiveModule->InferredSubmoduleLoc = StarLoc;
1995 ActiveModule->InferExplicitSubmodules = Explicit;
1996 } else {
1997 // We'll be inferring framework modules for this directory.
1998 Map.InferredDirectories[Directory].InferModules = true;
1999 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
Stephen Hines651f13c2014-04-23 16:59:28 -07002000 // FIXME: Handle the 'framework' keyword.
Douglas Gregor82e52372012-11-06 19:39:40 +00002001 }
2002
Douglas Gregor1e123682011-12-05 22:27:44 +00002003 // Parse the opening brace.
2004 if (!Tok.is(MMToken::LBrace)) {
2005 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2006 HadError = true;
2007 return;
2008 }
2009 SourceLocation LBraceLoc = consumeToken();
2010
2011 // Parse the body of the inferred submodule.
2012 bool Done = false;
2013 do {
2014 switch (Tok.Kind) {
2015 case MMToken::EndOfFile:
2016 case MMToken::RBrace:
2017 Done = true;
2018 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00002019
2020 case MMToken::ExcludeKeyword: {
2021 if (ActiveModule) {
2022 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00002023 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00002024 consumeToken();
2025 break;
2026 }
2027
2028 consumeToken();
2029 if (!Tok.is(MMToken::Identifier)) {
2030 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2031 break;
2032 }
2033
2034 Map.InferredDirectories[Directory].ExcludedModules
2035 .push_back(Tok.getString());
2036 consumeToken();
2037 break;
2038 }
2039
2040 case MMToken::ExportKeyword:
2041 if (!ActiveModule) {
2042 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00002043 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00002044 consumeToken();
2045 break;
2046 }
2047
Douglas Gregor1e123682011-12-05 22:27:44 +00002048 consumeToken();
2049 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00002050 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00002051 else
2052 Diags.Report(Tok.getLocation(),
2053 diag::err_mmap_expected_export_wildcard);
2054 consumeToken();
2055 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00002056
Douglas Gregor1e123682011-12-05 22:27:44 +00002057 case MMToken::ExplicitKeyword:
2058 case MMToken::ModuleKeyword:
2059 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00002060 case MMToken::PrivateKeyword:
Douglas Gregor1e123682011-12-05 22:27:44 +00002061 case MMToken::UmbrellaKeyword:
2062 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00002063 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00002064 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00002065 consumeToken();
2066 break;
2067 }
2068 } while (!Done);
2069
2070 if (Tok.is(MMToken::RBrace))
2071 consumeToken();
2072 else {
2073 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2074 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2075 HadError = true;
2076 }
2077}
2078
Douglas Gregor82e52372012-11-06 19:39:40 +00002079/// \brief Parse optional attributes.
2080///
2081/// attributes:
2082/// attribute attributes
2083/// attribute
2084///
2085/// attribute:
2086/// [ identifier ]
2087///
2088/// \param Attrs Will be filled in with the parsed attributes.
2089///
2090/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00002091bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00002092 bool HadError = false;
2093
2094 while (Tok.is(MMToken::LSquare)) {
2095 // Consume the '['.
2096 SourceLocation LSquareLoc = consumeToken();
2097
2098 // Check whether we have an attribute name here.
2099 if (!Tok.is(MMToken::Identifier)) {
2100 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2101 skipUntil(MMToken::RSquare);
2102 if (Tok.is(MMToken::RSquare))
2103 consumeToken();
2104 HadError = true;
2105 }
2106
2107 // Decode the attribute name.
2108 AttributeKind Attribute
2109 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00002110 .Case("exhaustive", AT_exhaustive)
Stephen Hines651f13c2014-04-23 16:59:28 -07002111 .Case("extern_c", AT_extern_c)
Douglas Gregor82e52372012-11-06 19:39:40 +00002112 .Case("system", AT_system)
2113 .Default(AT_unknown);
2114 switch (Attribute) {
2115 case AT_unknown:
2116 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2117 << Tok.getString();
2118 break;
2119
2120 case AT_system:
2121 Attrs.IsSystem = true;
2122 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00002123
Stephen Hines651f13c2014-04-23 16:59:28 -07002124 case AT_extern_c:
2125 Attrs.IsExternC = true;
2126 break;
2127
Douglas Gregor63a72682013-03-20 00:22:05 +00002128 case AT_exhaustive:
2129 Attrs.IsExhaustive = true;
2130 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00002131 }
2132 consumeToken();
2133
2134 // Consume the ']'.
2135 if (!Tok.is(MMToken::RSquare)) {
2136 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2137 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2138 skipUntil(MMToken::RSquare);
2139 HadError = true;
2140 }
2141
2142 if (Tok.is(MMToken::RSquare))
2143 consumeToken();
2144 }
2145
2146 return HadError;
2147}
2148
Douglas Gregor6a1db482011-12-09 02:04:43 +00002149/// \brief If there is a specific header search directory due the presence
2150/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
2151const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
2152 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
2153 // If we have an umbrella directory, use that.
2154 if (Mod->hasUmbrellaDir())
2155 return Mod->getUmbrellaDir();
2156
2157 // If we have a framework directory, stop looking.
2158 if (Mod->IsFramework)
2159 return 0;
2160 }
2161
2162 return 0;
2163}
2164
Douglas Gregora30cfe52011-11-11 19:10:28 +00002165/// \brief Parse a module map file.
2166///
2167/// module-map-file:
2168/// module-declaration*
2169bool ModuleMapParser::parseModuleMapFile() {
2170 do {
2171 switch (Tok.Kind) {
2172 case MMToken::EndOfFile:
2173 return HadError;
2174
Douglas Gregor587986e2011-12-07 02:23:45 +00002175 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00002176 case MMToken::ExternKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002177 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00002178 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002179 parseModuleDecl();
2180 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00002181
Douglas Gregor51f564f2011-12-31 04:05:44 +00002182 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00002183 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00002184 case MMToken::Conflict:
Richard Smith5794b532013-10-28 22:18:19 +00002185 case MMToken::Exclaim:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00002186 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00002187 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002188 case MMToken::HeaderKeyword:
2189 case MMToken::Identifier:
2190 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00002191 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00002192 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00002193 case MMToken::Period:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00002194 case MMToken::PrivateKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002195 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00002196 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00002197 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00002198 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002199 case MMToken::StringLiteral:
2200 case MMToken::UmbrellaKeyword:
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00002201 case MMToken::UseKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002202 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2203 HadError = true;
2204 consumeToken();
2205 break;
2206 }
2207 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002208}
2209
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002210bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor7005b902013-01-10 01:43:00 +00002211 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2212 = ParsedModuleMap.find(File);
2213 if (Known != ParsedModuleMap.end())
2214 return Known->second;
2215
Douglas Gregordc58aa72012-01-30 06:01:29 +00002216 assert(Target != 0 && "Missing target information");
Stephen Hines651f13c2014-04-23 16:59:28 -07002217 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2218 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimekee0cd372013-10-24 07:51:24 +00002219 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002220 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00002221 return ParsedModuleMap[File] = true;
Stephen Hines651f13c2014-04-23 16:59:28 -07002222
2223 // Find the directory for the module. For frameworks, that may require going
2224 // up from the 'Modules' directory.
2225 const DirectoryEntry *Dir = File->getDir();
2226 StringRef DirName(Dir->getName());
2227 if (llvm::sys::path::filename(DirName) == "Modules") {
2228 DirName = llvm::sys::path::parent_path(DirName);
2229 if (DirName.endswith(".framework"))
2230 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2231 assert(Dir && "parent must exist");
2232 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00002233
2234 // Parse this module map file.
Manuel Klimekee0cd372013-10-24 07:51:24 +00002235 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Stephen Hines651f13c2014-04-23 16:59:28 -07002236 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, Dir,
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002237 BuiltinIncludeDir, IsSystem);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002238 bool Result = Parser.parseModuleMapFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00002239 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00002240 return Result;
2241}