blob: a6d1d82a36756d5799af71e86452c2496c5c97c2 [file] [log] [blame]
Douglas Gregor718292f2011-11-11 19:10:28 +00001//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ModuleMap implementation, which describes the layout
11// of a module as it relates to headers.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/Lex/ModuleMap.h"
Jordan Rosea7d03842013-02-08 22:30:41 +000015#include "clang/Basic/CharInfo.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000016#include "clang/Basic/Diagnostic.h"
Douglas Gregor811db4e2012-10-23 22:26:28 +000017#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000018#include "clang/Basic/FileManager.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Basic/TargetOptions.h"
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000021#include "clang/Lex/HeaderSearch.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000022#include "clang/Lex/LexDiagnostic.h"
23#include "clang/Lex/Lexer.h"
24#include "clang/Lex/LiteralSupport.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/ADT/StringSwitch.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000027#include "llvm/Support/Allocator.h"
Douglas Gregore89dbc12011-12-06 19:39:29 +000028#include "llvm/Support/FileSystem.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000029#include "llvm/Support/Host.h"
Rafael Espindola552c1692013-06-11 22:15:02 +000030#include "llvm/Support/Path.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000031#include "llvm/Support/raw_ostream.h"
Douglas Gregor07c22b72012-09-27 14:50:15 +000032#include <stdlib.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000033#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoeadae012013-01-26 16:29:36 +000034#include <limits.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000035#endif
Douglas Gregor718292f2011-11-11 19:10:28 +000036using namespace clang;
37
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000038Module::ExportDecl
39ModuleMap::resolveExport(Module *Mod,
40 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +000041 bool Complain) const {
Douglas Gregorf5eedd02011-12-05 17:28:06 +000042 // We may have just a wildcard.
43 if (Unresolved.Id.empty()) {
44 assert(Unresolved.Wildcard && "Invalid unresolved export");
Craig Topperd2d442c2014-05-17 23:10:59 +000045 return Module::ExportDecl(nullptr, true);
Douglas Gregorf5eedd02011-12-05 17:28:06 +000046 }
47
Douglas Gregorfb912652013-03-20 21:10:35 +000048 // Resolve the module-id.
49 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
50 if (!Context)
51 return Module::ExportDecl();
52
53 return Module::ExportDecl(Context, Unresolved.Wildcard);
54}
55
56Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
57 bool Complain) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000058 // Find the starting module.
Douglas Gregorfb912652013-03-20 21:10:35 +000059 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000060 if (!Context) {
61 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000062 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
Douglas Gregorfb912652013-03-20 21:10:35 +000063 << Id[0].first << Mod->getFullModuleName();
64
Craig Topperd2d442c2014-05-17 23:10:59 +000065 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000066 }
67
68 // Dig into the module path.
Douglas Gregorfb912652013-03-20 21:10:35 +000069 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
70 Module *Sub = lookupModuleQualified(Id[I].first, Context);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000071 if (!Sub) {
72 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000073 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Douglas Gregorfb912652013-03-20 21:10:35 +000074 << Id[I].first << Context->getFullModuleName()
75 << SourceRange(Id[0].second, Id[I-1].second);
76
Craig Topperd2d442c2014-05-17 23:10:59 +000077 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000078 }
Douglas Gregorfb912652013-03-20 21:10:35 +000079
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000080 Context = Sub;
81 }
Douglas Gregorfb912652013-03-20 21:10:35 +000082
83 return Context;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000084}
85
Daniel Jasper0761a8a2013-12-17 10:31:37 +000086ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000087 const LangOptions &LangOpts, const TargetInfo *Target,
88 HeaderSearch &HeaderInfo)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000089 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
Craig Topperd2d442c2014-05-17 23:10:59 +000090 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
91 CompilingModule(nullptr), SourceModule(nullptr) {}
Douglas Gregor718292f2011-11-11 19:10:28 +000092
93ModuleMap::~ModuleMap() {
Douglas Gregor5acdf592011-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 Gregor718292f2011-11-11 19:10:28 +000099}
100
Douglas Gregor89929282012-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 Gregor056396a2012-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 Rosea7d03842013-02-08 22:30:41 +0000113 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-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 Rosea7d03842013-02-08 22:30:41 +0000117 if (isDigit(Name[0]))
Douglas Gregor056396a2012-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 Rosea7d03842013-02-08 22:30:41 +0000121 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-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 Gregor34d52742013-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
Daniel Jasper92669ee2013-12-20 12:09:36 +0000162ModuleMap::HeadersMap::iterator
163ModuleMap::findKnownHeader(const FileEntry *File) {
Douglas Gregor59527662012-10-15 06:28:11 +0000164 HeadersMap::iterator Known = Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000165 if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
166 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
167 HeaderInfo.loadTopLevelSystemModules();
Daniel Jasper92669ee2013-12-20 12:09:36 +0000168 return Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000169 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000170 return Known;
171}
172
Ben Langmuir44691382014-04-10 00:39:10 +0000173ModuleMap::KnownHeader
174ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
175 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
176 const DirectoryEntry *Dir = File->getDir();
177 assert(Dir && "file in no directory");
178
179 // Note: as an egregious but useful hack we use the real path here, because
180 // frameworks moving from top-level frameworks to embedded frameworks tend
181 // to be symlinked from the top-level location to the embedded location,
182 // and we need to resolve lookups as if we had found the embedded location.
183 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
184
185 // Keep walking up the directory hierarchy, looking for a directory with
186 // an umbrella header.
187 do {
188 auto KnownDir = UmbrellaDirs.find(Dir);
189 if (KnownDir != UmbrellaDirs.end())
190 return KnownHeader(KnownDir->second, NormalHeader);
191
192 IntermediateDirs.push_back(Dir);
193
194 // Retrieve our parent path.
195 DirName = llvm::sys::path::parent_path(DirName);
196 if (DirName.empty())
197 break;
198
199 // Resolve the parent path to a directory entry.
200 Dir = SourceMgr.getFileManager().getDirectory(DirName);
201 } while (Dir);
202 return KnownHeader();
203}
204
Daniel Jasper92669ee2013-12-20 12:09:36 +0000205// Returns 'true' if 'RequestingModule directly uses 'RequestedModule'.
206static bool directlyUses(const Module *RequestingModule,
207 const Module *RequestedModule) {
208 return std::find(RequestingModule->DirectUses.begin(),
209 RequestingModule->DirectUses.end(),
210 RequestedModule) != RequestingModule->DirectUses.end();
211}
212
213static bool violatesPrivateInclude(Module *RequestingModule,
214 const FileEntry *IncFileEnt,
215 ModuleMap::ModuleHeaderRole Role,
216 Module *RequestedModule) {
217 #ifndef NDEBUG
218 // Check for consistency between the module header role
219 // as obtained from the lookup and as obtained from the module.
220 // This check is not cheap, so enable it only for debugging.
221 SmallVectorImpl<const FileEntry *> &PvtHdrs
222 = RequestedModule->PrivateHeaders;
223 SmallVectorImpl<const FileEntry *>::iterator Look
224 = std::find(PvtHdrs.begin(), PvtHdrs.end(), IncFileEnt);
225 bool IsPrivate = Look != PvtHdrs.end();
226 assert((IsPrivate && Role == ModuleMap::PrivateHeader)
227 || (!IsPrivate && Role != ModuleMap::PrivateHeader));
228 #endif
229 return Role == ModuleMap::PrivateHeader &&
230 RequestedModule->getTopLevelModule() != RequestingModule;
231}
232
Ben Langmuir71e1a642014-05-05 21:44:13 +0000233static Module *getTopLevelOrNull(Module *M) {
234 return M ? M->getTopLevelModule() : nullptr;
235}
236
Daniel Jasper92669ee2013-12-20 12:09:36 +0000237void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
238 SourceLocation FilenameLoc,
239 StringRef Filename,
240 const FileEntry *File) {
241 // No errors for indirect modules. This may be a bit of a problem for modules
242 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000243 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000244 return;
245
246 if (RequestingModule)
247 resolveUses(RequestingModule, /*Complain=*/false);
248
Ben Langmuir71e1a642014-05-05 21:44:13 +0000249 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000250 Module *Private = nullptr;
251 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000252
Ben Langmuir71e1a642014-05-05 21:44:13 +0000253 HeadersMap::iterator Known = findKnownHeader(File);
254 if (Known != Headers.end()) {
255 for (const KnownHeader &Header : Known->second) {
256 // Excluded headers don't really belong to a module.
257 if (Header.getRole() == ModuleMap::ExcludedHeader) {
258 Excluded = true;
259 continue;
260 }
261
262 // If 'File' is part of 'RequestingModule' we can definitely include it.
263 if (Header.getModule() == RequestingModule)
264 return;
265
266 // Remember private headers for later printing of a diagnostic.
267 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
268 Header.getModule())) {
269 Private = Header.getModule();
270 continue;
271 }
272
273 // If uses need to be specified explicitly, we are only allowed to return
274 // modules that are explicitly used by the requesting module.
275 if (RequestingModule && LangOpts.ModulesDeclUse &&
276 !directlyUses(RequestingModule, Header.getModule())) {
277 NotUsed = Header.getModule();
278 continue;
279 }
280
281 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000282 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000283 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000284 }
285
286 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000287 if (Private) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000288 Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module)
289 << Filename;
290 return;
291 }
292
293 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000294 if (NotUsed) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000295 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
296 << RequestingModule->getFullModuleName() << Filename;
297 return;
298 }
299
Ben Langmuir71e1a642014-05-05 21:44:13 +0000300 if (Excluded || isHeaderInUmbrellaDirs(File))
301 return;
302
303 // At this point, only non-modular includes remain.
304
305 if (LangOpts.ModulesStrictDeclUse) {
306 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
307 << RequestingModule->getFullModuleName() << Filename;
308 } else if (RequestingModule) {
309 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
310 diag::warn_non_modular_include_in_framework_module :
311 diag::warn_non_modular_include_in_module;
312 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000313 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000314}
315
316ModuleMap::KnownHeader
317ModuleMap::findModuleForHeader(const FileEntry *File,
318 Module *RequestingModule) {
319 HeadersMap::iterator Known = findKnownHeader(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000320
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000321 if (Known != Headers.end()) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000322 ModuleMap::KnownHeader Result = KnownHeader();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000323
Daniel Jasper97da9172013-10-22 08:09:47 +0000324 // Iterate over all modules that 'File' is part of to find the best fit.
325 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
326 E = Known->second.end();
327 I != E; ++I) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000328 // Cannot use a module if the header is excluded in it.
329 if (I->getRole() == ModuleMap::ExcludedHeader)
330 continue;
331
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000332 // Cannot use a module if it is unavailable.
333 if (!I->getModule()->isAvailable())
Daniel Jasper97da9172013-10-22 08:09:47 +0000334 continue;
335
336 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
337 // module we are looking for.
338 if (I->getModule() == RequestingModule)
339 return *I;
340
341 // If uses need to be specified explicitly, we are only allowed to return
342 // modules that are explicitly used by the requesting module.
343 if (RequestingModule && LangOpts.ModulesDeclUse &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000344 !directlyUses(RequestingModule, I->getModule()))
Daniel Jasper97da9172013-10-22 08:09:47 +0000345 continue;
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000346
Daniel Jasper97da9172013-10-22 08:09:47 +0000347 Result = *I;
348 // If 'File' is a public header of this module, this is as good as we
349 // are going to get.
Richard Smith8c71eba2014-03-05 20:51:45 +0000350 // FIXME: If we have a RequestingModule, we should prefer the header from
351 // that module.
Daniel Jasper97da9172013-10-22 08:09:47 +0000352 if (I->getRole() == ModuleMap::NormalHeader)
353 break;
354 }
355 return Result;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000356 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000357
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000358 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000359 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
360 if (H) {
361 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000362
Ben Langmuir44691382014-04-10 00:39:10 +0000363 // Search up the module stack until we find a module with an umbrella
364 // directory.
365 Module *UmbrellaModule = Result;
366 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
367 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000368
Ben Langmuir44691382014-04-10 00:39:10 +0000369 if (UmbrellaModule->InferSubmodules) {
370 // Infer submodules for each of the directories we found between
371 // the directory of the umbrella header and the directory where
372 // the actual header is located.
373 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000374
Ben Langmuir44691382014-04-10 00:39:10 +0000375 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
376 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000377 SmallString<32> NameBuf;
378 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000379 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000380 Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap,
381 /*IsFramework=*/false, Explicit).first;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000382 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000383
384 // Associate the module and the directory.
385 UmbrellaDirs[SkippedDirs[I-1]] = Result;
386
387 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000388 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000389 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000390 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000391 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000392
Ben Langmuir44691382014-04-10 00:39:10 +0000393 // Infer a submodule with the same name as this header file.
394 SmallString<32> NameBuf;
395 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000396 llvm::sys::path::stem(File->getName()), NameBuf);
397 Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap,
398 /*IsFramework=*/false, Explicit).first;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000399 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000400 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000401
Ben Langmuir44691382014-04-10 00:39:10 +0000402 // If inferred submodules export everything they import, add a
403 // wildcard to the set of exports.
404 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000405 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000406 } else {
407 // Record each of the directories we stepped through as being part of
408 // the module we found, since the umbrella header covers them all.
409 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
410 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000411 }
Ben Langmuir44691382014-04-10 00:39:10 +0000412
413 Headers[File].push_back(KnownHeader(Result, NormalHeader));
414
415 // If a header corresponds to an unavailable module, don't report
416 // that it maps to anything.
417 if (!Result->isAvailable())
418 return KnownHeader();
419
420 return Headers[File].back();
421 }
Douglas Gregorb65dbff2011-11-16 23:02:25 +0000422
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000423 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000424}
425
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000426bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000427 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000428}
429
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000430bool
431ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
432 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000433 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000434 if (Known != Headers.end()) {
435 for (SmallVectorImpl<KnownHeader>::const_iterator
436 I = Known->second.begin(),
437 E = Known->second.end();
438 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000439 if (I->isAvailable() && (!RequestingModule ||
440 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000441 return false;
442 }
443 return true;
444 }
Richard Smith50996ce2014-04-08 13:13:04 +0000445
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000446 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000447 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000448 StringRef DirName = Dir->getName();
449
Richard Smith50996ce2014-04-08 13:13:04 +0000450 auto IsUnavailable = [&](const Module *M) {
451 return !M->isAvailable() && (!RequestingModule ||
452 M->isSubModuleOf(RequestingModule));
453 };
454
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000455 // Keep walking up the directory hierarchy, looking for a directory with
456 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000457 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000458 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000459 = UmbrellaDirs.find(Dir);
460 if (KnownDir != UmbrellaDirs.end()) {
461 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000462 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000463 return true;
464
465 // Search up the module stack until we find a module with an umbrella
466 // directory.
467 Module *UmbrellaModule = Found;
468 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
469 UmbrellaModule = UmbrellaModule->Parent;
470
471 if (UmbrellaModule->InferSubmodules) {
472 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
473 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000474 SmallString<32> NameBuf;
475 StringRef Name = sanitizeFilenameAsIdentifier(
476 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
477 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000478 Found = lookupModuleQualified(Name, Found);
479 if (!Found)
480 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000481 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000482 return true;
483 }
484
485 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000486 SmallString<32> NameBuf;
487 StringRef Name = sanitizeFilenameAsIdentifier(
488 llvm::sys::path::stem(Header->getName()),
489 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000490 Found = lookupModuleQualified(Name, Found);
491 if (!Found)
492 return false;
493 }
494
Richard Smith50996ce2014-04-08 13:13:04 +0000495 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000496 }
497
498 SkippedDirs.push_back(Dir);
499
500 // Retrieve our parent path.
501 DirName = llvm::sys::path::parent_path(DirName);
502 if (DirName.empty())
503 break;
504
505 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000506 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000507 } while (Dir);
508
509 return false;
510}
511
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000512Module *ModuleMap::findModule(StringRef Name) const {
513 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000514 if (Known != Modules.end())
515 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000516
517 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000518}
519
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000520Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
521 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000522 for(; Context; Context = Context->Parent) {
523 if (Module *Sub = lookupModuleQualified(Name, Context))
524 return Sub;
525 }
526
527 return findModule(Name);
528}
529
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000530Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000531 if (!Context)
532 return findModule(Name);
533
Douglas Gregoreb90e832012-01-04 23:32:19 +0000534 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000535}
536
Douglas Gregorde3ef502011-11-30 23:21:26 +0000537std::pair<Module *, bool>
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000538ModuleMap::findOrCreateModule(StringRef Name, Module *Parent,
539 const FileEntry *ModuleMap, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000540 bool IsExplicit) {
541 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000542 if (Module *Sub = lookupModuleQualified(Name, Parent))
543 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000544
545 // Create a new module with this name.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000546 Module *Result = new Module(Name, SourceLocation(), Parent, ModuleMap,
547 IsFramework, IsExplicit);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000548 if (LangOpts.CurrentModule == Name) {
549 SourceModule = Result;
550 SourceModuleName = Name;
551 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000552 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000553 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000554 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
555 Name == LangOpts.CurrentModule) {
556 CompilingModule = Result;
557 }
558 }
Douglas Gregor69021972011-11-30 17:33:56 +0000559 return std::make_pair(Result, true);
560}
561
Douglas Gregor9194a912012-11-06 19:39:40 +0000562bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000563 StringRef Name, bool &IsSystem) const {
Douglas Gregor9194a912012-11-06 19:39:40 +0000564 // Check whether we have already looked into the parent directory
565 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000566 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000567 inferred = InferredDirectories.find(ParentDir);
568 if (inferred == InferredDirectories.end())
569 return false;
570
571 if (!inferred->second.InferModules)
572 return false;
573
574 // We're allowed to infer for this directory, but make sure it's okay
575 // to infer this particular module.
576 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
577 inferred->second.ExcludedModules.end(),
578 Name) == inferred->second.ExcludedModules.end();
579
580 if (canInfer && inferred->second.InferSystemModules)
581 IsSystem = true;
582
583 return canInfer;
584}
585
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000586/// \brief For a framework module, infer the framework against which we
587/// should link.
588static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
589 FileManager &FileMgr) {
590 assert(Mod->IsFramework && "Can only infer linking for framework modules");
591 assert(!Mod->isSubFramework() &&
592 "Can only infer linking for top-level frameworks");
593
594 SmallString<128> LibName;
595 LibName += FrameworkDir->getName();
596 llvm::sys::path::append(LibName, Mod->Name);
597 if (FileMgr.getFile(LibName)) {
598 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
599 /*IsFramework=*/true));
600 }
601}
602
Douglas Gregorde3ef502011-11-30 23:21:26 +0000603Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000604ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000605 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000606 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000607 Module *Parent) {
Douglas Gregor56c64012011-11-17 01:41:17 +0000608 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000609 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
610 return Mod;
611
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000612 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000613
614 // If the framework has a parent path from which we're allowed to infer
615 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000616 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000617 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000618 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000619
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000620 // Note: as an egregious but useful hack we use the real path here, because
621 // we might be looking at an embedded framework that symlinks out to a
622 // top-level framework, and we need to infer as if we were naming the
623 // top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000624 StringRef FrameworkDirName
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000625 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000626
Douglas Gregor9194a912012-11-06 19:39:40 +0000627 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000628 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000629 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000630 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000631 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
632 // Check whether we have already looked into the parent directory
633 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000634 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000635 inferred = InferredDirectories.find(ParentDir);
636 if (inferred == InferredDirectories.end()) {
637 // We haven't looked here before. Load a module map, if there is
638 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000639 bool IsFrameworkDir = Parent.endswith(".framework");
640 if (const FileEntry *ModMapFile =
641 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Douglas Gregor963c5532013-06-21 16:28:10 +0000642 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor9194a912012-11-06 19:39:40 +0000643 inferred = InferredDirectories.find(ParentDir);
644 }
645
646 if (inferred == InferredDirectories.end())
647 inferred = InferredDirectories.insert(
648 std::make_pair(ParentDir, InferredDirectory())).first;
649 }
650
651 if (inferred->second.InferModules) {
652 // We're allowed to infer for this directory, but make sure it's okay
653 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000654 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000655 canInfer = std::find(inferred->second.ExcludedModules.begin(),
656 inferred->second.ExcludedModules.end(),
657 Name) == inferred->second.ExcludedModules.end();
658
659 if (inferred->second.InferSystemModules)
660 IsSystem = true;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000661 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000662 }
663 }
664 }
665
666 // If we're not allowed to infer a framework module, don't.
667 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000668 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000669 } else
670 ModuleMapFile = Parent->ModuleMap;
Douglas Gregor9194a912012-11-06 19:39:40 +0000671
672
Douglas Gregor56c64012011-11-17 01:41:17 +0000673 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000674 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000675 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000676 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000677
678 // FIXME: If there's no umbrella header, we could probably scan the
679 // framework to load *everything*. But, it's not clear that this is a good
680 // idea.
681 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000682 return nullptr;
683
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000684 Module *Result = new Module(ModuleName, SourceLocation(), Parent, ModuleMapFile,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000685 /*IsFramework=*/true, /*IsExplicit=*/false);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000686 if (LangOpts.CurrentModule == ModuleName) {
687 SourceModule = Result;
688 SourceModuleName = ModuleName;
689 }
Douglas Gregora686e1b2012-01-27 19:52:33 +0000690 if (IsSystem)
691 Result->IsSystem = IsSystem;
692
Douglas Gregoreb90e832012-01-04 23:32:19 +0000693 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000694 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000695
Douglas Gregor322f6332011-12-08 18:00:48 +0000696 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000697 Result->Umbrella = UmbrellaHeader;
Daniel Jasper97da9172013-10-22 08:09:47 +0000698 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor4dc71832011-12-12 23:55:05 +0000699 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000700
701 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000702 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
703
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000704 // module * { export * }
705 Result->InferSubmodules = true;
706 Result->InferExportWildcard = true;
707
Douglas Gregore89dbc12011-12-06 19:39:29 +0000708 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000709 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000710 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000711 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000712 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000713 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000714 for (llvm::sys::fs::directory_iterator
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000715 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000716 Dir != DirEnd && !EC; Dir.increment(EC)) {
717 if (!StringRef(Dir->path()).endswith(".framework"))
718 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000719
Douglas Gregore89dbc12011-12-06 19:39:29 +0000720 if (const DirectoryEntry *SubframeworkDir
721 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000722 // Note: as an egregious but useful hack, we use the real path here and
723 // check whether it is actually a subdirectory of the parent directory.
724 // This will not be the case if the 'subframework' is actually a symlink
725 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000726 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
727 bool FoundParent = false;
728 do {
729 // Get the parent directory name.
730 SubframeworkDirName
731 = llvm::sys::path::parent_path(SubframeworkDirName);
732 if (SubframeworkDirName.empty())
733 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000734
Douglas Gregore00c8b22013-01-26 00:55:12 +0000735 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
736 FoundParent = true;
737 break;
738 }
739 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000740
Douglas Gregore00c8b22013-01-26 00:55:12 +0000741 if (!FoundParent)
742 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000743
Douglas Gregore89dbc12011-12-06 19:39:29 +0000744 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-10-12 21:15:50 +0000745 SmallString<32> NameBuf;
746 inferFrameworkModule(sanitizeFilenameAsIdentifier(
747 llvm::sys::path::stem(Dir->path()), NameBuf),
748 SubframeworkDir, IsSystem, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000749 }
750 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000751
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000752 // If the module is a top-level framework, automatically link against the
753 // framework.
754 if (!Result->isSubFramework()) {
755 inferFrameworkLink(Result, FrameworkDir, FileMgr);
756 }
757
Douglas Gregor56c64012011-11-17 01:41:17 +0000758 return Result;
759}
760
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000761void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasper97da9172013-10-22 08:09:47 +0000762 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000763 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000764 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000765}
766
Douglas Gregor524e33e2011-12-08 19:11:24 +0000767void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
768 Mod->Umbrella = UmbrellaDir;
769 UmbrellaDirs[UmbrellaDir] = Mod;
770}
771
Douglas Gregor59527662012-10-15 06:28:11 +0000772void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000773 ModuleHeaderRole Role) {
774 if (Role == ExcludedHeader) {
Douglas Gregor59527662012-10-15 06:28:11 +0000775 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000776 } else {
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000777 if (Role == PrivateHeader)
778 Mod->PrivateHeaders.push_back(Header);
779 else
780 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000781 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000782 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000783 }
Daniel Jasper97da9172013-10-22 08:09:47 +0000784 Headers[Header].push_back(KnownHeader(Mod, Role));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000785}
786
Douglas Gregor514b6362011-11-29 19:06:37 +0000787const FileEntry *
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000788ModuleMap::getContainingModuleMapFile(Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000789 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000790 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000791
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000792 return SourceMgr.getFileEntryForID(
793 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000794}
795
Douglas Gregor718292f2011-11-11 19:10:28 +0000796void ModuleMap::dump() {
797 llvm::errs() << "Modules:";
798 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
799 MEnd = Modules.end();
800 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000801 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000802
803 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000804 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000805 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000806 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
807 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
808 E = H->second.end();
809 I != E; ++I) {
810 if (I != H->second.begin())
811 llvm::errs() << ",";
812 llvm::errs() << I->getModule()->getFullModuleName();
813 }
814 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000815 }
816}
817
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000818bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
819 bool HadError = false;
820 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
821 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
822 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000823 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000824 Mod->Exports.push_back(Export);
825 else
826 HadError = true;
827 }
828 Mod->UnresolvedExports.clear();
829 return HadError;
830}
831
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000832bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
833 bool HadError = false;
834 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
835 Module *DirectUse =
836 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
837 if (DirectUse)
838 Mod->DirectUses.push_back(DirectUse);
839 else
840 HadError = true;
841 }
842 Mod->UnresolvedDirectUses.clear();
843 return HadError;
844}
845
Douglas Gregorfb912652013-03-20 21:10:35 +0000846bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
847 bool HadError = false;
848 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
849 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
850 Mod, Complain);
851 if (!OtherMod) {
852 HadError = true;
853 continue;
854 }
855
856 Module::Conflict Conflict;
857 Conflict.Other = OtherMod;
858 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
859 Mod->Conflicts.push_back(Conflict);
860 }
861 Mod->UnresolvedConflicts.clear();
862 return HadError;
863}
864
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000865Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
866 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000867 return nullptr;
868
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000869 // Use the expansion location to determine which module we're in.
870 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
871 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000872 return nullptr;
873
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000874 const SourceManager &SrcMgr = Loc.getManager();
875 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000876
Douglas Gregor224d8a72012-01-06 17:19:32 +0000877 while (const FileEntry *ExpansionFile
878 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
879 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000880 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000881 return Mod;
882
883 // No module owns this header, so look up the inclusion chain to see if
884 // any included header has an associated module.
885 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
886 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000887 return nullptr;
888
Douglas Gregor224d8a72012-01-06 17:19:32 +0000889 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
890 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000891
892 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000893}
894
Douglas Gregor718292f2011-11-11 19:10:28 +0000895//----------------------------------------------------------------------------//
896// Module map file parser
897//----------------------------------------------------------------------------//
898
899namespace clang {
900 /// \brief A token in a module map file.
901 struct MMToken {
902 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000903 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000904 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000905 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000906 EndOfFile,
907 HeaderKeyword,
908 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000909 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000910 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000911 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000912 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000913 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000914 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000915 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000916 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000917 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000918 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000919 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000920 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000921 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000922 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000923 StringLiteral,
924 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000925 RBrace,
926 LSquare,
927 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000928 } Kind;
929
930 unsigned Location;
931 unsigned StringLength;
932 const char *StringData;
933
934 void clear() {
935 Kind = EndOfFile;
936 Location = 0;
937 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000938 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000939 }
940
941 bool is(TokenKind K) const { return Kind == K; }
942
943 SourceLocation getLocation() const {
944 return SourceLocation::getFromRawEncoding(Location);
945 }
946
947 StringRef getString() const {
948 return StringRef(StringData, StringLength);
949 }
950 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000951
952 /// \brief The set of attributes that can be attached to a module.
Bill Wendling44426052012-12-20 19:22:21 +0000953 struct Attributes {
Richard Smith77944862014-03-02 05:58:18 +0000954 Attributes() : IsSystem(), IsExternC(), IsExhaustive() { }
Douglas Gregor9194a912012-11-06 19:39:40 +0000955
956 /// \brief Whether this is a system module.
957 unsigned IsSystem : 1;
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000958
Richard Smith77944862014-03-02 05:58:18 +0000959 /// \brief Whether this is an extern "C" module.
960 unsigned IsExternC : 1;
961
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000962 /// \brief Whether this is an exhaustive set of configuration macros.
963 unsigned IsExhaustive : 1;
Douglas Gregor9194a912012-11-06 19:39:40 +0000964 };
Douglas Gregor718292f2011-11-11 19:10:28 +0000965
Douglas Gregor9194a912012-11-06 19:39:40 +0000966
Douglas Gregor718292f2011-11-11 19:10:28 +0000967 class ModuleMapParser {
968 Lexer &L;
969 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000970
971 /// \brief Default target information, used only for string literal
972 /// parsing.
973 const TargetInfo *Target;
974
Douglas Gregor718292f2011-11-11 19:10:28 +0000975 DiagnosticsEngine &Diags;
976 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000977
978 /// \brief The current module map file.
979 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +0000980
Douglas Gregor5257fc62011-11-11 21:55:48 +0000981 /// \brief The directory that this module map resides in.
982 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +0000983
984 /// \brief The directory containing Clang-supplied headers.
985 const DirectoryEntry *BuiltinIncludeDir;
986
Douglas Gregor963c5532013-06-21 16:28:10 +0000987 /// \brief Whether this module map is in a system header directory.
988 bool IsSystem;
989
Douglas Gregor718292f2011-11-11 19:10:28 +0000990 /// \brief Whether an error occurred.
991 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000992
Douglas Gregor718292f2011-11-11 19:10:28 +0000993 /// \brief Stores string data for the various string literals referenced
994 /// during parsing.
995 llvm::BumpPtrAllocator StringData;
996
997 /// \brief The current token.
998 MMToken Tok;
999
1000 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001001 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001002
1003 /// \brief Consume the current token and return its location.
1004 SourceLocation consumeToken();
1005
1006 /// \brief Skip tokens until we reach the a token with the given kind
1007 /// (or the end of the file).
1008 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001009
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001010 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001011 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001012 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001013 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001014 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001015 void parseHeaderDecl(clang::MMToken::TokenKind,
1016 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001017 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001018 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001019 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001020 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001021 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001022 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001023 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendling44426052012-12-20 19:22:21 +00001024 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001025
Douglas Gregor718292f2011-11-11 19:10:28 +00001026 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001027 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001028 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001029 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001030 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001031 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001032 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001033 const DirectoryEntry *BuiltinIncludeDir,
1034 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001035 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001036 ModuleMapFile(ModuleMapFile), Directory(Directory),
1037 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001038 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001039 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001040 Tok.clear();
1041 consumeToken();
1042 }
1043
1044 bool parseModuleMapFile();
1045 };
1046}
1047
1048SourceLocation ModuleMapParser::consumeToken() {
1049retry:
1050 SourceLocation Result = Tok.getLocation();
1051 Tok.clear();
1052
1053 Token LToken;
1054 L.LexFromRawLexer(LToken);
1055 Tok.Location = LToken.getLocation().getRawEncoding();
1056 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001057 case tok::raw_identifier: {
1058 StringRef RI = LToken.getRawIdentifier();
1059 Tok.StringData = RI.data();
1060 Tok.StringLength = RI.size();
1061 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001062 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001063 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001064 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001065 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001066 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001067 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001068 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001069 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001070 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001071 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001072 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001073 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001074 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001075 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001076 .Default(MMToken::Identifier);
1077 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001078 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001079
1080 case tok::comma:
1081 Tok.Kind = MMToken::Comma;
1082 break;
1083
Douglas Gregor718292f2011-11-11 19:10:28 +00001084 case tok::eof:
1085 Tok.Kind = MMToken::EndOfFile;
1086 break;
1087
1088 case tok::l_brace:
1089 Tok.Kind = MMToken::LBrace;
1090 break;
1091
Douglas Gregora686e1b2012-01-27 19:52:33 +00001092 case tok::l_square:
1093 Tok.Kind = MMToken::LSquare;
1094 break;
1095
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001096 case tok::period:
1097 Tok.Kind = MMToken::Period;
1098 break;
1099
Douglas Gregor718292f2011-11-11 19:10:28 +00001100 case tok::r_brace:
1101 Tok.Kind = MMToken::RBrace;
1102 break;
1103
Douglas Gregora686e1b2012-01-27 19:52:33 +00001104 case tok::r_square:
1105 Tok.Kind = MMToken::RSquare;
1106 break;
1107
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001108 case tok::star:
1109 Tok.Kind = MMToken::Star;
1110 break;
1111
Richard Smitha3feee22013-10-28 22:18:19 +00001112 case tok::exclaim:
1113 Tok.Kind = MMToken::Exclaim;
1114 break;
1115
Douglas Gregor718292f2011-11-11 19:10:28 +00001116 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001117 if (LToken.hasUDSuffix()) {
1118 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1119 HadError = true;
1120 goto retry;
1121 }
1122
Douglas Gregor718292f2011-11-11 19:10:28 +00001123 // Parse the string literal.
1124 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001125 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001126 if (StringLiteral.hadError)
1127 goto retry;
1128
1129 // Copy the string literal into our string data allocator.
1130 unsigned Length = StringLiteral.GetStringLength();
1131 char *Saved = StringData.Allocate<char>(Length + 1);
1132 memcpy(Saved, StringLiteral.GetString().data(), Length);
1133 Saved[Length] = 0;
1134
1135 // Form the token.
1136 Tok.Kind = MMToken::StringLiteral;
1137 Tok.StringData = Saved;
1138 Tok.StringLength = Length;
1139 break;
1140 }
1141
1142 case tok::comment:
1143 goto retry;
1144
1145 default:
1146 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1147 HadError = true;
1148 goto retry;
1149 }
1150
1151 return Result;
1152}
1153
1154void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1155 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001156 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001157 do {
1158 switch (Tok.Kind) {
1159 case MMToken::EndOfFile:
1160 return;
1161
1162 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001163 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001164 return;
1165
1166 ++braceDepth;
1167 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001168
1169 case MMToken::LSquare:
1170 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1171 return;
1172
1173 ++squareDepth;
1174 break;
1175
Douglas Gregor718292f2011-11-11 19:10:28 +00001176 case MMToken::RBrace:
1177 if (braceDepth > 0)
1178 --braceDepth;
1179 else if (Tok.is(K))
1180 return;
1181 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001182
1183 case MMToken::RSquare:
1184 if (squareDepth > 0)
1185 --squareDepth;
1186 else if (Tok.is(K))
1187 return;
1188 break;
1189
Douglas Gregor718292f2011-11-11 19:10:28 +00001190 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001191 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001192 return;
1193 break;
1194 }
1195
1196 consumeToken();
1197 } while (true);
1198}
1199
Douglas Gregore7ab3662011-12-07 02:23:45 +00001200/// \brief Parse a module-id.
1201///
1202/// module-id:
1203/// identifier
1204/// identifier '.' module-id
1205///
1206/// \returns true if an error occurred, false otherwise.
1207bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1208 Id.clear();
1209 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001210 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001211 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1212 consumeToken();
1213 } else {
1214 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1215 return true;
1216 }
1217
1218 if (!Tok.is(MMToken::Period))
1219 break;
1220
1221 consumeToken();
1222 } while (true);
1223
1224 return false;
1225}
1226
Douglas Gregora686e1b2012-01-27 19:52:33 +00001227namespace {
1228 /// \brief Enumerates the known attributes.
1229 enum AttributeKind {
1230 /// \brief An unknown attribute.
1231 AT_unknown,
1232 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001233 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001234 /// \brief The 'extern_c' attribute.
1235 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001236 /// \brief The 'exhaustive' attribute.
1237 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001238 };
1239}
1240
Douglas Gregor718292f2011-11-11 19:10:28 +00001241/// \brief Parse a module declaration.
1242///
1243/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001244/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001245/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1246/// { module-member* }
1247///
Douglas Gregor718292f2011-11-11 19:10:28 +00001248/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001249/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001250/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001251/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001252/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001253/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001254///
1255/// submodule-declaration:
1256/// module-declaration
1257/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001258void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001259 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001260 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1261 if (Tok.is(MMToken::ExternKeyword)) {
1262 parseExternModuleDecl();
1263 return;
1264 }
1265
Douglas Gregorf2161a72011-12-06 17:16:41 +00001266 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001267 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001268 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001269 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001270
Douglas Gregorf2161a72011-12-06 17:16:41 +00001271 // Parse 'explicit' keyword, if present.
1272 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001273 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001274 Explicit = true;
1275 }
1276
1277 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001278 if (Tok.is(MMToken::FrameworkKeyword)) {
1279 consumeToken();
1280 Framework = true;
1281 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001282
1283 // Parse 'module' keyword.
1284 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001285 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001286 consumeToken();
1287 HadError = true;
1288 return;
1289 }
1290 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001291
1292 // If we have a wildcard for the module name, this is an inferred submodule.
1293 // Parse it.
1294 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001295 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001296
1297 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001298 ModuleId Id;
1299 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001300 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001301 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001302 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001303
Douglas Gregore7ab3662011-12-07 02:23:45 +00001304 if (ActiveModule) {
1305 if (Id.size() > 1) {
1306 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1307 << SourceRange(Id.front().second, Id.back().second);
1308
1309 HadError = true;
1310 return;
1311 }
1312 } else if (Id.size() == 1 && Explicit) {
1313 // Top-level modules can't be explicit.
1314 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1315 Explicit = false;
1316 ExplicitLoc = SourceLocation();
1317 HadError = true;
1318 }
1319
1320 Module *PreviousActiveModule = ActiveModule;
1321 if (Id.size() > 1) {
1322 // This module map defines a submodule. Go find the module of which it
1323 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001324 ActiveModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001325 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1326 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1327 ActiveModule = Next;
1328 continue;
1329 }
1330
1331 if (ActiveModule) {
1332 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001333 << Id[I].first
1334 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001335 } else {
1336 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1337 }
1338 HadError = true;
1339 return;
1340 }
1341 }
1342
1343 StringRef ModuleName = Id.back().first;
1344 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001345
Douglas Gregora686e1b2012-01-27 19:52:33 +00001346 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001347 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001348 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001349
Douglas Gregor718292f2011-11-11 19:10:28 +00001350 // Parse the opening brace.
1351 if (!Tok.is(MMToken::LBrace)) {
1352 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1353 << ModuleName;
1354 HadError = true;
1355 return;
1356 }
1357 SourceLocation LBraceLoc = consumeToken();
1358
1359 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001360 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001361 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1362 // Skip the module definition.
1363 skipUntil(MMToken::RBrace);
1364 if (Tok.is(MMToken::RBrace))
1365 consumeToken();
1366 else {
1367 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1368 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1369 HadError = true;
1370 }
1371 return;
1372 }
1373
Douglas Gregor718292f2011-11-11 19:10:28 +00001374 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1375 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001376 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001377
1378 // Skip the module definition.
1379 skipUntil(MMToken::RBrace);
1380 if (Tok.is(MMToken::RBrace))
1381 consumeToken();
1382
1383 HadError = true;
1384 return;
1385 }
1386
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001387 // If this is a submodule, use the parent's module map, since we don't want
1388 // the private module map file.
1389 const FileEntry *ModuleMap = ActiveModule ? ActiveModule->ModuleMap
1390 : ModuleMapFile;
1391
Douglas Gregor718292f2011-11-11 19:10:28 +00001392 // Start defining this module.
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001393 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, ModuleMap,
1394 Framework, Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001395 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001396 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001397 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001398 if (Attrs.IsExternC)
1399 ActiveModule->IsExternC = true;
1400
Douglas Gregor718292f2011-11-11 19:10:28 +00001401 bool Done = false;
1402 do {
1403 switch (Tok.Kind) {
1404 case MMToken::EndOfFile:
1405 case MMToken::RBrace:
1406 Done = true;
1407 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001408
1409 case MMToken::ConfigMacros:
1410 parseConfigMacros();
1411 break;
1412
Douglas Gregorfb912652013-03-20 21:10:35 +00001413 case MMToken::Conflict:
1414 parseConflict();
1415 break;
1416
Douglas Gregor718292f2011-11-11 19:10:28 +00001417 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001418 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001419 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001420 case MMToken::ModuleKeyword:
1421 parseModuleDecl();
1422 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001423
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001424 case MMToken::ExportKeyword:
1425 parseExportDecl();
1426 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001427
1428 case MMToken::UseKeyword:
1429 parseUseDecl();
1430 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001431
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001432 case MMToken::RequiresKeyword:
1433 parseRequiresDecl();
1434 break;
1435
Douglas Gregor524e33e2011-12-08 19:11:24 +00001436 case MMToken::UmbrellaKeyword: {
1437 SourceLocation UmbrellaLoc = consumeToken();
1438 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001439 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001440 else
1441 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001442 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001443 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001444
Douglas Gregor59527662012-10-15 06:28:11 +00001445 case MMToken::ExcludeKeyword: {
1446 SourceLocation ExcludeLoc = consumeToken();
1447 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001448 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor59527662012-10-15 06:28:11 +00001449 } else {
1450 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1451 << "exclude";
1452 }
1453 break;
1454 }
1455
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001456 case MMToken::PrivateKeyword: {
1457 SourceLocation PrivateLoc = consumeToken();
1458 if (Tok.is(MMToken::HeaderKeyword)) {
1459 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1460 } else {
1461 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1462 << "private";
1463 }
1464 break;
1465 }
1466
Douglas Gregor322f6332011-12-08 18:00:48 +00001467 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001468 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregor718292f2011-11-11 19:10:28 +00001469 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001470
1471 case MMToken::LinkKeyword:
1472 parseLinkDecl();
1473 break;
1474
Douglas Gregor718292f2011-11-11 19:10:28 +00001475 default:
1476 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1477 consumeToken();
1478 break;
1479 }
1480 } while (!Done);
1481
1482 if (Tok.is(MMToken::RBrace))
1483 consumeToken();
1484 else {
1485 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1486 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1487 HadError = true;
1488 }
1489
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001490 // If the active module is a top-level framework, and there are no link
1491 // libraries, automatically link against the framework.
1492 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1493 ActiveModule->LinkLibraries.empty()) {
1494 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1495 }
1496
Ben Langmuirec8c9752014-04-18 22:07:31 +00001497 // If the module meets all requirements but is still unavailable, mark the
1498 // whole tree as unavailable to prevent it from building.
1499 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1500 ActiveModule->Parent) {
1501 ActiveModule->getTopLevelModule()->markUnavailable();
1502 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1503 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1504 }
1505
Douglas Gregore7ab3662011-12-07 02:23:45 +00001506 // We're done parsing this module. Pop back to the previous module.
1507 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001508}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001509
Daniel Jasper97292842013-09-11 07:20:44 +00001510/// \brief Parse an extern module declaration.
1511///
1512/// extern module-declaration:
1513/// 'extern' 'module' module-id string-literal
1514void ModuleMapParser::parseExternModuleDecl() {
1515 assert(Tok.is(MMToken::ExternKeyword));
1516 consumeToken(); // 'extern' keyword
1517
1518 // Parse 'module' keyword.
1519 if (!Tok.is(MMToken::ModuleKeyword)) {
1520 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1521 consumeToken();
1522 HadError = true;
1523 return;
1524 }
1525 consumeToken(); // 'module' keyword
1526
1527 // Parse the module name.
1528 ModuleId Id;
1529 if (parseModuleId(Id)) {
1530 HadError = true;
1531 return;
1532 }
1533
1534 // Parse the referenced module map file name.
1535 if (!Tok.is(MMToken::StringLiteral)) {
1536 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1537 HadError = true;
1538 return;
1539 }
1540 std::string FileName = Tok.getString();
1541 consumeToken(); // filename
1542
1543 StringRef FileNameRef = FileName;
1544 SmallString<128> ModuleMapFileName;
1545 if (llvm::sys::path::is_relative(FileNameRef)) {
1546 ModuleMapFileName += Directory->getName();
1547 llvm::sys::path::append(ModuleMapFileName, FileName);
1548 FileNameRef = ModuleMapFileName.str();
1549 }
1550 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1551 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1552}
1553
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001554/// \brief Parse a requires declaration.
1555///
1556/// requires-declaration:
1557/// 'requires' feature-list
1558///
1559/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001560/// feature ',' feature-list
1561/// feature
1562///
1563/// feature:
1564/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001565void ModuleMapParser::parseRequiresDecl() {
1566 assert(Tok.is(MMToken::RequiresKeyword));
1567
1568 // Parse 'requires' keyword.
1569 consumeToken();
1570
1571 // Parse the feature-list.
1572 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001573 bool RequiredState = true;
1574 if (Tok.is(MMToken::Exclaim)) {
1575 RequiredState = false;
1576 consumeToken();
1577 }
1578
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001579 if (!Tok.is(MMToken::Identifier)) {
1580 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1581 HadError = true;
1582 return;
1583 }
1584
1585 // Consume the feature name.
1586 std::string Feature = Tok.getString();
1587 consumeToken();
1588
1589 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001590 ActiveModule->addRequirement(Feature, RequiredState,
1591 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001592
1593 if (!Tok.is(MMToken::Comma))
1594 break;
1595
1596 // Consume the comma.
1597 consumeToken();
1598 } while (true);
1599}
1600
Douglas Gregorf2161a72011-12-06 17:16:41 +00001601/// \brief Append to \p Paths the set of paths needed to get to the
1602/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001603static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001604 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001605 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001606 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001607 for (; Mod; Mod = Mod->Parent) {
1608 if (Mod->IsFramework)
1609 Paths.push_back(Mod->Name);
1610 }
1611
1612 if (Paths.empty())
1613 return;
1614
1615 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001616 for (unsigned I = Paths.size() - 1; I != 0; --I)
1617 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001618}
1619
Douglas Gregor718292f2011-11-11 19:10:28 +00001620/// \brief Parse a header declaration.
1621///
1622/// header-declaration:
Douglas Gregor322f6332011-12-08 18:00:48 +00001623/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor59527662012-10-15 06:28:11 +00001624/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001625void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1626 SourceLocation LeadingLoc) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001627 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001628 consumeToken();
1629
Douglas Gregor718292f2011-11-11 19:10:28 +00001630 // Parse the header name.
1631 if (!Tok.is(MMToken::StringLiteral)) {
1632 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1633 << "header";
1634 HadError = true;
1635 return;
1636 }
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001637 Module::HeaderDirective Header;
1638 Header.FileName = Tok.getString();
1639 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001640
Douglas Gregor524e33e2011-12-08 19:11:24 +00001641 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001642 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001643 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001644 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001645 HadError = true;
1646 return;
1647 }
1648
Douglas Gregor5257fc62011-11-11 21:55:48 +00001649 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001650 const FileEntry *File = nullptr;
1651 const FileEntry *BuiltinFile = nullptr;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001652 SmallString<128> PathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001653 if (llvm::sys::path::is_absolute(Header.FileName)) {
1654 PathName = Header.FileName;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001655 File = SourceMgr.getFileManager().getFile(PathName);
1656 } else {
1657 // Search for the header file within the search directory.
Douglas Gregor70331272011-12-09 02:04:43 +00001658 PathName = Directory->getName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001659 unsigned PathLength = PathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001660
Douglas Gregorf2161a72011-12-06 17:16:41 +00001661 if (ActiveModule->isPartOfFramework()) {
1662 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001663
1664 // Check whether this file is in the public headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001665 llvm::sys::path::append(PathName, "Headers", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001666 File = SourceMgr.getFileManager().getFile(PathName);
1667
1668 if (!File) {
1669 // Check whether this file is in the private headers.
1670 PathName.resize(PathLength);
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001671 llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001672 File = SourceMgr.getFileManager().getFile(PathName);
1673 }
1674 } else {
1675 // Lookup for normal headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001676 llvm::sys::path::append(PathName, Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001677 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001678
1679 // If this is a system module with a top-level header, this header
1680 // may have a counterpart (or replacement) in the set of headers
1681 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001682 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1683 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001684 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001685 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001686 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001687 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1688
1689 // If Clang supplies this header but the underlying system does not,
1690 // just silently swap in our builtin version. Otherwise, we'll end
1691 // up adding both (later).
1692 if (!File && BuiltinFile) {
1693 File = BuiltinFile;
Craig Topperd2d442c2014-05-17 23:10:59 +00001694 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001695 }
1696 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001697 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001698 }
Douglas Gregor755b2052011-11-17 22:09:43 +00001699
Douglas Gregor5257fc62011-11-11 21:55:48 +00001700 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1701 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001702 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001703 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001704 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001705 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001706 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001707 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001708 HadError = true;
1709 } else {
1710 // Record this umbrella header.
1711 Map.setUmbrellaHeader(ActiveModule, File);
1712 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00001713 } else {
Douglas Gregor322f6332011-12-08 18:00:48 +00001714 // Record this header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001715 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1716 if (LeadingToken == MMToken::ExcludeKeyword)
1717 Role = ModuleMap::ExcludedHeader;
1718 else if (LeadingToken == MMToken::PrivateKeyword)
1719 Role = ModuleMap::PrivateHeader;
1720 else
1721 assert(LeadingToken == MMToken::HeaderKeyword);
1722
1723 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001724
1725 // If there is a builtin counterpart to this file, add it now.
1726 if (BuiltinFile)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001727 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001728 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001729 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001730 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001731
1732 // If we find a module that has a missing header, we mark this module as
1733 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001734 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001735 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001736 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001737 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001738}
1739
Douglas Gregor524e33e2011-12-08 19:11:24 +00001740/// \brief Parse an umbrella directory declaration.
1741///
1742/// umbrella-dir-declaration:
1743/// umbrella string-literal
1744void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1745 // Parse the directory name.
1746 if (!Tok.is(MMToken::StringLiteral)) {
1747 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1748 << "umbrella";
1749 HadError = true;
1750 return;
1751 }
1752
1753 std::string DirName = Tok.getString();
1754 SourceLocation DirNameLoc = consumeToken();
1755
1756 // Check whether we already have an umbrella.
1757 if (ActiveModule->Umbrella) {
1758 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1759 << ActiveModule->getFullModuleName();
1760 HadError = true;
1761 return;
1762 }
1763
1764 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001765 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001766 if (llvm::sys::path::is_absolute(DirName))
1767 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1768 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001769 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001770 PathName = Directory->getName();
1771 llvm::sys::path::append(PathName, DirName);
1772 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1773 }
1774
1775 if (!Dir) {
1776 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1777 << DirName;
1778 HadError = true;
1779 return;
1780 }
1781
1782 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1783 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1784 << OwningModule->getFullModuleName();
1785 HadError = true;
1786 return;
1787 }
1788
1789 // Record this umbrella directory.
1790 Map.setUmbrellaDir(ActiveModule, Dir);
1791}
1792
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001793/// \brief Parse a module export declaration.
1794///
1795/// export-declaration:
1796/// 'export' wildcard-module-id
1797///
1798/// wildcard-module-id:
1799/// identifier
1800/// '*'
1801/// identifier '.' wildcard-module-id
1802void ModuleMapParser::parseExportDecl() {
1803 assert(Tok.is(MMToken::ExportKeyword));
1804 SourceLocation ExportLoc = consumeToken();
1805
1806 // Parse the module-id with an optional wildcard at the end.
1807 ModuleId ParsedModuleId;
1808 bool Wildcard = false;
1809 do {
1810 if (Tok.is(MMToken::Identifier)) {
1811 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1812 Tok.getLocation()));
1813 consumeToken();
1814
1815 if (Tok.is(MMToken::Period)) {
1816 consumeToken();
1817 continue;
1818 }
1819
1820 break;
1821 }
1822
1823 if(Tok.is(MMToken::Star)) {
1824 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001825 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001826 break;
1827 }
1828
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001829 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001830 HadError = true;
1831 return;
1832 } while (true);
1833
1834 Module::UnresolvedExportDecl Unresolved = {
1835 ExportLoc, ParsedModuleId, Wildcard
1836 };
1837 ActiveModule->UnresolvedExports.push_back(Unresolved);
1838}
1839
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001840/// \brief Parse a module uses declaration.
1841///
1842/// uses-declaration:
1843/// 'uses' wildcard-module-id
1844void ModuleMapParser::parseUseDecl() {
1845 assert(Tok.is(MMToken::UseKeyword));
1846 consumeToken();
1847 // Parse the module-id.
1848 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001849 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001850
1851 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1852}
1853
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001854/// \brief Parse a link declaration.
1855///
1856/// module-declaration:
1857/// 'link' 'framework'[opt] string-literal
1858void ModuleMapParser::parseLinkDecl() {
1859 assert(Tok.is(MMToken::LinkKeyword));
1860 SourceLocation LinkLoc = consumeToken();
1861
1862 // Parse the optional 'framework' keyword.
1863 bool IsFramework = false;
1864 if (Tok.is(MMToken::FrameworkKeyword)) {
1865 consumeToken();
1866 IsFramework = true;
1867 }
1868
1869 // Parse the library name
1870 if (!Tok.is(MMToken::StringLiteral)) {
1871 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1872 << IsFramework << SourceRange(LinkLoc);
1873 HadError = true;
1874 return;
1875 }
1876
1877 std::string LibraryName = Tok.getString();
1878 consumeToken();
1879 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1880 IsFramework));
1881}
1882
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001883/// \brief Parse a configuration macro declaration.
1884///
1885/// module-declaration:
1886/// 'config_macros' attributes[opt] config-macro-list?
1887///
1888/// config-macro-list:
1889/// identifier (',' identifier)?
1890void ModuleMapParser::parseConfigMacros() {
1891 assert(Tok.is(MMToken::ConfigMacros));
1892 SourceLocation ConfigMacrosLoc = consumeToken();
1893
1894 // Only top-level modules can have configuration macros.
1895 if (ActiveModule->Parent) {
1896 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1897 }
1898
1899 // Parse the optional attributes.
1900 Attributes Attrs;
1901 parseOptionalAttributes(Attrs);
1902 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1903 ActiveModule->ConfigMacrosExhaustive = true;
1904 }
1905
1906 // If we don't have an identifier, we're done.
1907 if (!Tok.is(MMToken::Identifier))
1908 return;
1909
1910 // Consume the first identifier.
1911 if (!ActiveModule->Parent) {
1912 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1913 }
1914 consumeToken();
1915
1916 do {
1917 // If there's a comma, consume it.
1918 if (!Tok.is(MMToken::Comma))
1919 break;
1920 consumeToken();
1921
1922 // We expect to see a macro name here.
1923 if (!Tok.is(MMToken::Identifier)) {
1924 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1925 break;
1926 }
1927
1928 // Consume the macro name.
1929 if (!ActiveModule->Parent) {
1930 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1931 }
1932 consumeToken();
1933 } while (true);
1934}
1935
Douglas Gregorfb912652013-03-20 21:10:35 +00001936/// \brief Format a module-id into a string.
1937static std::string formatModuleId(const ModuleId &Id) {
1938 std::string result;
1939 {
1940 llvm::raw_string_ostream OS(result);
1941
1942 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1943 if (I)
1944 OS << ".";
1945 OS << Id[I].first;
1946 }
1947 }
1948
1949 return result;
1950}
1951
1952/// \brief Parse a conflict declaration.
1953///
1954/// module-declaration:
1955/// 'conflict' module-id ',' string-literal
1956void ModuleMapParser::parseConflict() {
1957 assert(Tok.is(MMToken::Conflict));
1958 SourceLocation ConflictLoc = consumeToken();
1959 Module::UnresolvedConflict Conflict;
1960
1961 // Parse the module-id.
1962 if (parseModuleId(Conflict.Id))
1963 return;
1964
1965 // Parse the ','.
1966 if (!Tok.is(MMToken::Comma)) {
1967 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1968 << SourceRange(ConflictLoc);
1969 return;
1970 }
1971 consumeToken();
1972
1973 // Parse the message.
1974 if (!Tok.is(MMToken::StringLiteral)) {
1975 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1976 << formatModuleId(Conflict.Id);
1977 return;
1978 }
1979 Conflict.Message = Tok.getString().str();
1980 consumeToken();
1981
1982 // Add this unresolved conflict.
1983 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1984}
1985
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001986/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00001987///
1988/// module-declaration:
1989/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1990/// { inferred-module-member* }
1991///
1992/// inferred-module-member:
1993/// 'export' '*'
1994/// 'exclude' identifier
1995void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00001996 assert(Tok.is(MMToken::Star));
1997 SourceLocation StarLoc = consumeToken();
1998 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00001999
Douglas Gregor73441092011-12-05 22:27:44 +00002000 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002001 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002002 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2003 Failed = true;
2004 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002005
2006 if (ActiveModule) {
2007 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002008 if (!Failed && ActiveModule->IsAvailable &&
2009 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002010 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2011 Failed = true;
2012 }
2013
2014 // Check for redefinition of an inferred module.
2015 if (!Failed && ActiveModule->InferSubmodules) {
2016 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2017 if (ActiveModule->InferredSubmoduleLoc.isValid())
2018 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2019 diag::note_mmap_prev_definition);
2020 Failed = true;
2021 }
2022
2023 // Check for the 'framework' keyword, which is not permitted here.
2024 if (Framework) {
2025 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2026 Framework = false;
2027 }
2028 } else if (Explicit) {
2029 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2030 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002031 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002032
Douglas Gregor73441092011-12-05 22:27:44 +00002033 // If there were any problems with this inferred submodule, skip its body.
2034 if (Failed) {
2035 if (Tok.is(MMToken::LBrace)) {
2036 consumeToken();
2037 skipUntil(MMToken::RBrace);
2038 if (Tok.is(MMToken::RBrace))
2039 consumeToken();
2040 }
2041 HadError = true;
2042 return;
2043 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002044
2045 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002046 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002047 parseOptionalAttributes(Attrs);
2048
2049 if (ActiveModule) {
2050 // Note that we have an inferred submodule.
2051 ActiveModule->InferSubmodules = true;
2052 ActiveModule->InferredSubmoduleLoc = StarLoc;
2053 ActiveModule->InferExplicitSubmodules = Explicit;
2054 } else {
2055 // We'll be inferring framework modules for this directory.
2056 Map.InferredDirectories[Directory].InferModules = true;
2057 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002058 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002059 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002060 }
2061
Douglas Gregor73441092011-12-05 22:27:44 +00002062 // Parse the opening brace.
2063 if (!Tok.is(MMToken::LBrace)) {
2064 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2065 HadError = true;
2066 return;
2067 }
2068 SourceLocation LBraceLoc = consumeToken();
2069
2070 // Parse the body of the inferred submodule.
2071 bool Done = false;
2072 do {
2073 switch (Tok.Kind) {
2074 case MMToken::EndOfFile:
2075 case MMToken::RBrace:
2076 Done = true;
2077 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002078
2079 case MMToken::ExcludeKeyword: {
2080 if (ActiveModule) {
2081 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002082 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002083 consumeToken();
2084 break;
2085 }
2086
2087 consumeToken();
2088 if (!Tok.is(MMToken::Identifier)) {
2089 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2090 break;
2091 }
2092
2093 Map.InferredDirectories[Directory].ExcludedModules
2094 .push_back(Tok.getString());
2095 consumeToken();
2096 break;
2097 }
2098
2099 case MMToken::ExportKeyword:
2100 if (!ActiveModule) {
2101 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002102 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002103 consumeToken();
2104 break;
2105 }
2106
Douglas Gregor73441092011-12-05 22:27:44 +00002107 consumeToken();
2108 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002109 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002110 else
2111 Diags.Report(Tok.getLocation(),
2112 diag::err_mmap_expected_export_wildcard);
2113 consumeToken();
2114 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002115
Douglas Gregor73441092011-12-05 22:27:44 +00002116 case MMToken::ExplicitKeyword:
2117 case MMToken::ModuleKeyword:
2118 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002119 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002120 case MMToken::UmbrellaKeyword:
2121 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002122 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002123 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002124 consumeToken();
2125 break;
2126 }
2127 } while (!Done);
2128
2129 if (Tok.is(MMToken::RBrace))
2130 consumeToken();
2131 else {
2132 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2133 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2134 HadError = true;
2135 }
2136}
2137
Douglas Gregor9194a912012-11-06 19:39:40 +00002138/// \brief Parse optional attributes.
2139///
2140/// attributes:
2141/// attribute attributes
2142/// attribute
2143///
2144/// attribute:
2145/// [ identifier ]
2146///
2147/// \param Attrs Will be filled in with the parsed attributes.
2148///
2149/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002150bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002151 bool HadError = false;
2152
2153 while (Tok.is(MMToken::LSquare)) {
2154 // Consume the '['.
2155 SourceLocation LSquareLoc = consumeToken();
2156
2157 // Check whether we have an attribute name here.
2158 if (!Tok.is(MMToken::Identifier)) {
2159 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2160 skipUntil(MMToken::RSquare);
2161 if (Tok.is(MMToken::RSquare))
2162 consumeToken();
2163 HadError = true;
2164 }
2165
2166 // Decode the attribute name.
2167 AttributeKind Attribute
2168 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002169 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002170 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002171 .Case("system", AT_system)
2172 .Default(AT_unknown);
2173 switch (Attribute) {
2174 case AT_unknown:
2175 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2176 << Tok.getString();
2177 break;
2178
2179 case AT_system:
2180 Attrs.IsSystem = true;
2181 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002182
Richard Smith77944862014-03-02 05:58:18 +00002183 case AT_extern_c:
2184 Attrs.IsExternC = true;
2185 break;
2186
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002187 case AT_exhaustive:
2188 Attrs.IsExhaustive = true;
2189 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002190 }
2191 consumeToken();
2192
2193 // Consume the ']'.
2194 if (!Tok.is(MMToken::RSquare)) {
2195 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2196 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2197 skipUntil(MMToken::RSquare);
2198 HadError = true;
2199 }
2200
2201 if (Tok.is(MMToken::RSquare))
2202 consumeToken();
2203 }
2204
2205 return HadError;
2206}
2207
Douglas Gregor718292f2011-11-11 19:10:28 +00002208/// \brief Parse a module map file.
2209///
2210/// module-map-file:
2211/// module-declaration*
2212bool ModuleMapParser::parseModuleMapFile() {
2213 do {
2214 switch (Tok.Kind) {
2215 case MMToken::EndOfFile:
2216 return HadError;
2217
Douglas Gregore7ab3662011-12-07 02:23:45 +00002218 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002219 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002220 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002221 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002222 parseModuleDecl();
2223 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002224
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002225 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002226 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002227 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002228 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002229 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002230 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002231 case MMToken::HeaderKeyword:
2232 case MMToken::Identifier:
2233 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002234 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002235 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002236 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002237 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002238 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002239 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002240 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002241 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002242 case MMToken::StringLiteral:
2243 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002244 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002245 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2246 HadError = true;
2247 consumeToken();
2248 break;
2249 }
2250 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002251}
2252
Douglas Gregor963c5532013-06-21 16:28:10 +00002253bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002254 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2255 = ParsedModuleMap.find(File);
2256 if (Known != ParsedModuleMap.end())
2257 return Known->second;
2258
Craig Topperd2d442c2014-05-17 23:10:59 +00002259 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002260 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2261 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002262 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002263 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002264 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002265
2266 // Find the directory for the module. For frameworks, that may require going
2267 // up from the 'Modules' directory.
2268 const DirectoryEntry *Dir = File->getDir();
2269 StringRef DirName(Dir->getName());
2270 if (llvm::sys::path::filename(DirName) == "Modules") {
2271 DirName = llvm::sys::path::parent_path(DirName);
2272 if (DirName.endswith(".framework"))
2273 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2274 assert(Dir && "parent must exist");
2275 }
Douglas Gregor718292f2011-11-11 19:10:28 +00002276
2277 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002278 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002279 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002280 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002281 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002282 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002283 return Result;
2284}