blob: 0af63e1bf44168635c892d221ac5c22fe7f173aa [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) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000370 const FileEntry *UmbrellaModuleMap =
371 getModuleMapFileForUniquing(UmbrellaModule);
372
Ben Langmuir44691382014-04-10 00:39:10 +0000373 // Infer submodules for each of the directories we found between
374 // the directory of the umbrella header and the directory where
375 // the actual header is located.
376 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000377
Ben Langmuir44691382014-04-10 00:39:10 +0000378 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
379 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000380 SmallString<32> NameBuf;
381 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000382 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000383 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
384 Explicit).first;
385 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000386 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000387
388 // Associate the module and the directory.
389 UmbrellaDirs[SkippedDirs[I-1]] = Result;
390
391 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000392 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000393 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000394 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000395 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000396
Ben Langmuir44691382014-04-10 00:39:10 +0000397 // Infer a submodule with the same name as this header file.
398 SmallString<32> NameBuf;
399 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000400 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000401 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
402 Explicit).first;
403 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000404 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000405 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000406
Ben Langmuir44691382014-04-10 00:39:10 +0000407 // If inferred submodules export everything they import, add a
408 // wildcard to the set of exports.
409 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000410 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000411 } else {
412 // Record each of the directories we stepped through as being part of
413 // the module we found, since the umbrella header covers them all.
414 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
415 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000416 }
Ben Langmuir44691382014-04-10 00:39:10 +0000417
418 Headers[File].push_back(KnownHeader(Result, NormalHeader));
419
420 // If a header corresponds to an unavailable module, don't report
421 // that it maps to anything.
422 if (!Result->isAvailable())
423 return KnownHeader();
424
425 return Headers[File].back();
426 }
Douglas Gregorb65dbff2011-11-16 23:02:25 +0000427
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000428 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000429}
430
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000431bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000432 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000433}
434
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000435bool
436ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
437 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000438 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000439 if (Known != Headers.end()) {
440 for (SmallVectorImpl<KnownHeader>::const_iterator
441 I = Known->second.begin(),
442 E = Known->second.end();
443 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000444 if (I->isAvailable() && (!RequestingModule ||
445 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000446 return false;
447 }
448 return true;
449 }
Richard Smith50996ce2014-04-08 13:13:04 +0000450
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000451 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000452 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000453 StringRef DirName = Dir->getName();
454
Richard Smith50996ce2014-04-08 13:13:04 +0000455 auto IsUnavailable = [&](const Module *M) {
456 return !M->isAvailable() && (!RequestingModule ||
457 M->isSubModuleOf(RequestingModule));
458 };
459
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000460 // Keep walking up the directory hierarchy, looking for a directory with
461 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000462 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000463 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000464 = UmbrellaDirs.find(Dir);
465 if (KnownDir != UmbrellaDirs.end()) {
466 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000467 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000468 return true;
469
470 // Search up the module stack until we find a module with an umbrella
471 // directory.
472 Module *UmbrellaModule = Found;
473 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
474 UmbrellaModule = UmbrellaModule->Parent;
475
476 if (UmbrellaModule->InferSubmodules) {
477 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
478 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000479 SmallString<32> NameBuf;
480 StringRef Name = sanitizeFilenameAsIdentifier(
481 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
482 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000483 Found = lookupModuleQualified(Name, Found);
484 if (!Found)
485 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000486 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000487 return true;
488 }
489
490 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000491 SmallString<32> NameBuf;
492 StringRef Name = sanitizeFilenameAsIdentifier(
493 llvm::sys::path::stem(Header->getName()),
494 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000495 Found = lookupModuleQualified(Name, Found);
496 if (!Found)
497 return false;
498 }
499
Richard Smith50996ce2014-04-08 13:13:04 +0000500 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000501 }
502
503 SkippedDirs.push_back(Dir);
504
505 // Retrieve our parent path.
506 DirName = llvm::sys::path::parent_path(DirName);
507 if (DirName.empty())
508 break;
509
510 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000511 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000512 } while (Dir);
513
514 return false;
515}
516
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000517Module *ModuleMap::findModule(StringRef Name) const {
518 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000519 if (Known != Modules.end())
520 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000521
522 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000523}
524
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000525Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
526 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000527 for(; Context; Context = Context->Parent) {
528 if (Module *Sub = lookupModuleQualified(Name, Context))
529 return Sub;
530 }
531
532 return findModule(Name);
533}
534
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000535Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000536 if (!Context)
537 return findModule(Name);
538
Douglas Gregoreb90e832012-01-04 23:32:19 +0000539 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000540}
541
Douglas Gregorde3ef502011-11-30 23:21:26 +0000542std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000543ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000544 bool IsExplicit) {
545 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000546 if (Module *Sub = lookupModuleQualified(Name, Parent))
547 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000548
549 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000550 Module *Result = new Module(Name, SourceLocation(), Parent,
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000551 IsFramework, IsExplicit);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000552 if (LangOpts.CurrentModule == Name) {
553 SourceModule = Result;
554 SourceModuleName = Name;
555 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000556 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000557 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000558 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
559 Name == LangOpts.CurrentModule) {
560 CompilingModule = Result;
561 }
562 }
Douglas Gregor69021972011-11-30 17:33:56 +0000563 return std::make_pair(Result, true);
564}
565
Douglas Gregor9194a912012-11-06 19:39:40 +0000566bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000567 StringRef Name, bool &IsSystem) const {
Douglas Gregor9194a912012-11-06 19:39:40 +0000568 // Check whether we have already looked into the parent directory
569 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000570 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000571 inferred = InferredDirectories.find(ParentDir);
572 if (inferred == InferredDirectories.end())
573 return false;
574
575 if (!inferred->second.InferModules)
576 return false;
577
578 // We're allowed to infer for this directory, but make sure it's okay
579 // to infer this particular module.
580 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
581 inferred->second.ExcludedModules.end(),
582 Name) == inferred->second.ExcludedModules.end();
583
584 if (canInfer && inferred->second.InferSystemModules)
585 IsSystem = true;
586
587 return canInfer;
588}
589
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000590/// \brief For a framework module, infer the framework against which we
591/// should link.
592static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
593 FileManager &FileMgr) {
594 assert(Mod->IsFramework && "Can only infer linking for framework modules");
595 assert(!Mod->isSubFramework() &&
596 "Can only infer linking for top-level frameworks");
597
598 SmallString<128> LibName;
599 LibName += FrameworkDir->getName();
600 llvm::sys::path::append(LibName, Mod->Name);
601 if (FileMgr.getFile(LibName)) {
602 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
603 /*IsFramework=*/true));
604 }
605}
606
Douglas Gregorde3ef502011-11-30 23:21:26 +0000607Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000608ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000609 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000610 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000611 Module *Parent) {
Douglas Gregor56c64012011-11-17 01:41:17 +0000612 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000613 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
614 return Mod;
615
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000616 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000617
618 // If the framework has a parent path from which we're allowed to infer
619 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000620 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000621 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000622 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000623
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000624 // Note: as an egregious but useful hack we use the real path here, because
625 // we might be looking at an embedded framework that symlinks out to a
626 // top-level framework, and we need to infer as if we were naming the
627 // top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000628 StringRef FrameworkDirName
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000629 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000630
Ben Langmuir6b7f7342014-07-14 19:45:12 +0000631 // In case this is a case-insensitive filesystem, make sure the canonical
632 // directory name matches ModuleName exactly. Modules are case-sensitive.
633 // FIXME: we should be able to give a fix-it hint for the correct spelling.
634 if (llvm::sys::path::stem(FrameworkDirName) != ModuleName)
635 return nullptr;
636
Douglas Gregor9194a912012-11-06 19:39:40 +0000637 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000638 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000639 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000640 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000641 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
642 // Check whether we have already looked into the parent directory
643 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000644 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000645 inferred = InferredDirectories.find(ParentDir);
646 if (inferred == InferredDirectories.end()) {
647 // We haven't looked here before. Load a module map, if there is
648 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000649 bool IsFrameworkDir = Parent.endswith(".framework");
650 if (const FileEntry *ModMapFile =
651 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Douglas Gregor963c5532013-06-21 16:28:10 +0000652 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor9194a912012-11-06 19:39:40 +0000653 inferred = InferredDirectories.find(ParentDir);
654 }
655
656 if (inferred == InferredDirectories.end())
657 inferred = InferredDirectories.insert(
658 std::make_pair(ParentDir, InferredDirectory())).first;
659 }
660
661 if (inferred->second.InferModules) {
662 // We're allowed to infer for this directory, but make sure it's okay
663 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000664 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000665 canInfer = std::find(inferred->second.ExcludedModules.begin(),
666 inferred->second.ExcludedModules.end(),
667 Name) == inferred->second.ExcludedModules.end();
668
669 if (inferred->second.InferSystemModules)
670 IsSystem = true;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000671 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000672 }
673 }
674 }
675
676 // If we're not allowed to infer a framework module, don't.
677 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000678 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000679 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000680 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000681
682
Douglas Gregor56c64012011-11-17 01:41:17 +0000683 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000684 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000685 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000686 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000687
688 // FIXME: If there's no umbrella header, we could probably scan the
689 // framework to load *everything*. But, it's not clear that this is a good
690 // idea.
691 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000692 return nullptr;
693
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000694 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000695 /*IsFramework=*/true, /*IsExplicit=*/false);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000696 InferredModuleAllowedBy[Result] = ModuleMapFile;
697 Result->IsInferred = true;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000698 if (LangOpts.CurrentModule == ModuleName) {
699 SourceModule = Result;
700 SourceModuleName = ModuleName;
701 }
Douglas Gregora686e1b2012-01-27 19:52:33 +0000702 if (IsSystem)
703 Result->IsSystem = IsSystem;
704
Douglas Gregoreb90e832012-01-04 23:32:19 +0000705 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000706 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000707
Douglas Gregor322f6332011-12-08 18:00:48 +0000708 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000709 Result->Umbrella = UmbrellaHeader;
Daniel Jasper97da9172013-10-22 08:09:47 +0000710 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor4dc71832011-12-12 23:55:05 +0000711 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000712
713 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000714 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
715
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000716 // module * { export * }
717 Result->InferSubmodules = true;
718 Result->InferExportWildcard = true;
719
Douglas Gregore89dbc12011-12-06 19:39:29 +0000720 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000721 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000722 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000723 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000724 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000725 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000726 for (llvm::sys::fs::directory_iterator
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000727 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000728 Dir != DirEnd && !EC; Dir.increment(EC)) {
729 if (!StringRef(Dir->path()).endswith(".framework"))
730 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000731
Douglas Gregore89dbc12011-12-06 19:39:29 +0000732 if (const DirectoryEntry *SubframeworkDir
733 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000734 // Note: as an egregious but useful hack, we use the real path here and
735 // check whether it is actually a subdirectory of the parent directory.
736 // This will not be the case if the 'subframework' is actually a symlink
737 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000738 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
739 bool FoundParent = false;
740 do {
741 // Get the parent directory name.
742 SubframeworkDirName
743 = llvm::sys::path::parent_path(SubframeworkDirName);
744 if (SubframeworkDirName.empty())
745 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000746
Douglas Gregore00c8b22013-01-26 00:55:12 +0000747 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
748 FoundParent = true;
749 break;
750 }
751 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000752
Douglas Gregore00c8b22013-01-26 00:55:12 +0000753 if (!FoundParent)
754 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000755
Douglas Gregore89dbc12011-12-06 19:39:29 +0000756 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-10-12 21:15:50 +0000757 SmallString<32> NameBuf;
758 inferFrameworkModule(sanitizeFilenameAsIdentifier(
759 llvm::sys::path::stem(Dir->path()), NameBuf),
760 SubframeworkDir, IsSystem, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000761 }
762 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000763
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000764 // If the module is a top-level framework, automatically link against the
765 // framework.
766 if (!Result->isSubFramework()) {
767 inferFrameworkLink(Result, FrameworkDir, FileMgr);
768 }
769
Douglas Gregor56c64012011-11-17 01:41:17 +0000770 return Result;
771}
772
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000773void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasper97da9172013-10-22 08:09:47 +0000774 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000775 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000776 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000777}
778
Douglas Gregor524e33e2011-12-08 19:11:24 +0000779void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
780 Mod->Umbrella = UmbrellaDir;
781 UmbrellaDirs[UmbrellaDir] = Mod;
782}
783
Douglas Gregor59527662012-10-15 06:28:11 +0000784void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000785 ModuleHeaderRole Role) {
786 if (Role == ExcludedHeader) {
Douglas Gregor59527662012-10-15 06:28:11 +0000787 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000788 } else {
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000789 if (Role == PrivateHeader)
790 Mod->PrivateHeaders.push_back(Header);
791 else
792 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000793 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000794 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000795 }
Daniel Jasper97da9172013-10-22 08:09:47 +0000796 Headers[Header].push_back(KnownHeader(Mod, Role));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000797}
798
Douglas Gregor514b6362011-11-29 19:06:37 +0000799const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000800ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000801 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000802 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000803
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000804 return SourceMgr.getFileEntryForID(
805 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000806}
807
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000808const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000809 if (M->IsInferred) {
810 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
811 return InferredModuleAllowedBy.find(M)->second;
812 }
813 return getContainingModuleMapFile(M);
814}
815
816void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
817 assert(M->IsInferred && "module not inferred");
818 InferredModuleAllowedBy[M] = ModMap;
819}
820
Douglas Gregor718292f2011-11-11 19:10:28 +0000821void ModuleMap::dump() {
822 llvm::errs() << "Modules:";
823 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
824 MEnd = Modules.end();
825 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000826 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000827
828 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000829 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000830 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000831 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
832 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
833 E = H->second.end();
834 I != E; ++I) {
835 if (I != H->second.begin())
836 llvm::errs() << ",";
837 llvm::errs() << I->getModule()->getFullModuleName();
838 }
839 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000840 }
841}
842
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000843bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
844 bool HadError = false;
845 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
846 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
847 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000848 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000849 Mod->Exports.push_back(Export);
850 else
851 HadError = true;
852 }
853 Mod->UnresolvedExports.clear();
854 return HadError;
855}
856
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000857bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
858 bool HadError = false;
859 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
860 Module *DirectUse =
861 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
862 if (DirectUse)
863 Mod->DirectUses.push_back(DirectUse);
864 else
865 HadError = true;
866 }
867 Mod->UnresolvedDirectUses.clear();
868 return HadError;
869}
870
Douglas Gregorfb912652013-03-20 21:10:35 +0000871bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
872 bool HadError = false;
873 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
874 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
875 Mod, Complain);
876 if (!OtherMod) {
877 HadError = true;
878 continue;
879 }
880
881 Module::Conflict Conflict;
882 Conflict.Other = OtherMod;
883 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
884 Mod->Conflicts.push_back(Conflict);
885 }
886 Mod->UnresolvedConflicts.clear();
887 return HadError;
888}
889
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000890Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
891 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000892 return nullptr;
893
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000894 // Use the expansion location to determine which module we're in.
895 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
896 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000897 return nullptr;
898
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000899 const SourceManager &SrcMgr = Loc.getManager();
900 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000901
Douglas Gregor224d8a72012-01-06 17:19:32 +0000902 while (const FileEntry *ExpansionFile
903 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
904 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000905 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000906 return Mod;
907
908 // No module owns this header, so look up the inclusion chain to see if
909 // any included header has an associated module.
910 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
911 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000912 return nullptr;
913
Douglas Gregor224d8a72012-01-06 17:19:32 +0000914 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
915 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000916
917 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000918}
919
Douglas Gregor718292f2011-11-11 19:10:28 +0000920//----------------------------------------------------------------------------//
921// Module map file parser
922//----------------------------------------------------------------------------//
923
924namespace clang {
925 /// \brief A token in a module map file.
926 struct MMToken {
927 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000928 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000929 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000930 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000931 EndOfFile,
932 HeaderKeyword,
933 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000934 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000935 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000936 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000937 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000938 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000939 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000940 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000941 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000942 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000943 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000944 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000945 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000946 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000947 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000948 StringLiteral,
949 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000950 RBrace,
951 LSquare,
952 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000953 } Kind;
954
955 unsigned Location;
956 unsigned StringLength;
957 const char *StringData;
958
959 void clear() {
960 Kind = EndOfFile;
961 Location = 0;
962 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000963 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000964 }
965
966 bool is(TokenKind K) const { return Kind == K; }
967
968 SourceLocation getLocation() const {
969 return SourceLocation::getFromRawEncoding(Location);
970 }
971
972 StringRef getString() const {
973 return StringRef(StringData, StringLength);
974 }
975 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000976
977 /// \brief The set of attributes that can be attached to a module.
Bill Wendling44426052012-12-20 19:22:21 +0000978 struct Attributes {
Richard Smith77944862014-03-02 05:58:18 +0000979 Attributes() : IsSystem(), IsExternC(), IsExhaustive() { }
Douglas Gregor9194a912012-11-06 19:39:40 +0000980
981 /// \brief Whether this is a system module.
982 unsigned IsSystem : 1;
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000983
Richard Smith77944862014-03-02 05:58:18 +0000984 /// \brief Whether this is an extern "C" module.
985 unsigned IsExternC : 1;
986
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000987 /// \brief Whether this is an exhaustive set of configuration macros.
988 unsigned IsExhaustive : 1;
Douglas Gregor9194a912012-11-06 19:39:40 +0000989 };
Douglas Gregor718292f2011-11-11 19:10:28 +0000990
Douglas Gregor9194a912012-11-06 19:39:40 +0000991
Douglas Gregor718292f2011-11-11 19:10:28 +0000992 class ModuleMapParser {
993 Lexer &L;
994 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000995
996 /// \brief Default target information, used only for string literal
997 /// parsing.
998 const TargetInfo *Target;
999
Douglas Gregor718292f2011-11-11 19:10:28 +00001000 DiagnosticsEngine &Diags;
1001 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001002
1003 /// \brief The current module map file.
1004 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001005
Douglas Gregor5257fc62011-11-11 21:55:48 +00001006 /// \brief The directory that this module map resides in.
1007 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001008
1009 /// \brief The directory containing Clang-supplied headers.
1010 const DirectoryEntry *BuiltinIncludeDir;
1011
Douglas Gregor963c5532013-06-21 16:28:10 +00001012 /// \brief Whether this module map is in a system header directory.
1013 bool IsSystem;
1014
Douglas Gregor718292f2011-11-11 19:10:28 +00001015 /// \brief Whether an error occurred.
1016 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001017
Douglas Gregor718292f2011-11-11 19:10:28 +00001018 /// \brief Stores string data for the various string literals referenced
1019 /// during parsing.
1020 llvm::BumpPtrAllocator StringData;
1021
1022 /// \brief The current token.
1023 MMToken Tok;
1024
1025 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001026 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001027
1028 /// \brief Consume the current token and return its location.
1029 SourceLocation consumeToken();
1030
1031 /// \brief Skip tokens until we reach the a token with the given kind
1032 /// (or the end of the file).
1033 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001034
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001035 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001036 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001037 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001038 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001039 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001040 void parseHeaderDecl(clang::MMToken::TokenKind,
1041 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001042 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001043 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001044 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001045 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001046 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001047 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001048 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendling44426052012-12-20 19:22:21 +00001049 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001050
Douglas Gregor718292f2011-11-11 19:10:28 +00001051 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001052 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001053 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001054 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001055 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001056 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001057 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001058 const DirectoryEntry *BuiltinIncludeDir,
1059 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001060 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001061 ModuleMapFile(ModuleMapFile), Directory(Directory),
1062 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001063 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001064 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001065 Tok.clear();
1066 consumeToken();
1067 }
1068
1069 bool parseModuleMapFile();
1070 };
1071}
1072
1073SourceLocation ModuleMapParser::consumeToken() {
1074retry:
1075 SourceLocation Result = Tok.getLocation();
1076 Tok.clear();
1077
1078 Token LToken;
1079 L.LexFromRawLexer(LToken);
1080 Tok.Location = LToken.getLocation().getRawEncoding();
1081 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001082 case tok::raw_identifier: {
1083 StringRef RI = LToken.getRawIdentifier();
1084 Tok.StringData = RI.data();
1085 Tok.StringLength = RI.size();
1086 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001087 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001088 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001089 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001090 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001091 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001092 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001093 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001094 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001095 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001096 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001097 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001098 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001099 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001100 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001101 .Default(MMToken::Identifier);
1102 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001103 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001104
1105 case tok::comma:
1106 Tok.Kind = MMToken::Comma;
1107 break;
1108
Douglas Gregor718292f2011-11-11 19:10:28 +00001109 case tok::eof:
1110 Tok.Kind = MMToken::EndOfFile;
1111 break;
1112
1113 case tok::l_brace:
1114 Tok.Kind = MMToken::LBrace;
1115 break;
1116
Douglas Gregora686e1b2012-01-27 19:52:33 +00001117 case tok::l_square:
1118 Tok.Kind = MMToken::LSquare;
1119 break;
1120
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001121 case tok::period:
1122 Tok.Kind = MMToken::Period;
1123 break;
1124
Douglas Gregor718292f2011-11-11 19:10:28 +00001125 case tok::r_brace:
1126 Tok.Kind = MMToken::RBrace;
1127 break;
1128
Douglas Gregora686e1b2012-01-27 19:52:33 +00001129 case tok::r_square:
1130 Tok.Kind = MMToken::RSquare;
1131 break;
1132
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001133 case tok::star:
1134 Tok.Kind = MMToken::Star;
1135 break;
1136
Richard Smitha3feee22013-10-28 22:18:19 +00001137 case tok::exclaim:
1138 Tok.Kind = MMToken::Exclaim;
1139 break;
1140
Douglas Gregor718292f2011-11-11 19:10:28 +00001141 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001142 if (LToken.hasUDSuffix()) {
1143 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1144 HadError = true;
1145 goto retry;
1146 }
1147
Douglas Gregor718292f2011-11-11 19:10:28 +00001148 // Parse the string literal.
1149 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001150 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001151 if (StringLiteral.hadError)
1152 goto retry;
1153
1154 // Copy the string literal into our string data allocator.
1155 unsigned Length = StringLiteral.GetStringLength();
1156 char *Saved = StringData.Allocate<char>(Length + 1);
1157 memcpy(Saved, StringLiteral.GetString().data(), Length);
1158 Saved[Length] = 0;
1159
1160 // Form the token.
1161 Tok.Kind = MMToken::StringLiteral;
1162 Tok.StringData = Saved;
1163 Tok.StringLength = Length;
1164 break;
1165 }
1166
1167 case tok::comment:
1168 goto retry;
1169
1170 default:
1171 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1172 HadError = true;
1173 goto retry;
1174 }
1175
1176 return Result;
1177}
1178
1179void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1180 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001181 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001182 do {
1183 switch (Tok.Kind) {
1184 case MMToken::EndOfFile:
1185 return;
1186
1187 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001188 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001189 return;
1190
1191 ++braceDepth;
1192 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001193
1194 case MMToken::LSquare:
1195 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1196 return;
1197
1198 ++squareDepth;
1199 break;
1200
Douglas Gregor718292f2011-11-11 19:10:28 +00001201 case MMToken::RBrace:
1202 if (braceDepth > 0)
1203 --braceDepth;
1204 else if (Tok.is(K))
1205 return;
1206 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001207
1208 case MMToken::RSquare:
1209 if (squareDepth > 0)
1210 --squareDepth;
1211 else if (Tok.is(K))
1212 return;
1213 break;
1214
Douglas Gregor718292f2011-11-11 19:10:28 +00001215 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001216 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001217 return;
1218 break;
1219 }
1220
1221 consumeToken();
1222 } while (true);
1223}
1224
Douglas Gregore7ab3662011-12-07 02:23:45 +00001225/// \brief Parse a module-id.
1226///
1227/// module-id:
1228/// identifier
1229/// identifier '.' module-id
1230///
1231/// \returns true if an error occurred, false otherwise.
1232bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1233 Id.clear();
1234 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001235 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001236 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1237 consumeToken();
1238 } else {
1239 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1240 return true;
1241 }
1242
1243 if (!Tok.is(MMToken::Period))
1244 break;
1245
1246 consumeToken();
1247 } while (true);
1248
1249 return false;
1250}
1251
Douglas Gregora686e1b2012-01-27 19:52:33 +00001252namespace {
1253 /// \brief Enumerates the known attributes.
1254 enum AttributeKind {
1255 /// \brief An unknown attribute.
1256 AT_unknown,
1257 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001258 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001259 /// \brief The 'extern_c' attribute.
1260 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001261 /// \brief The 'exhaustive' attribute.
1262 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001263 };
1264}
1265
Douglas Gregor718292f2011-11-11 19:10:28 +00001266/// \brief Parse a module declaration.
1267///
1268/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001269/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001270/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1271/// { module-member* }
1272///
Douglas Gregor718292f2011-11-11 19:10:28 +00001273/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001274/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001275/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001276/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001277/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001278/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001279///
1280/// submodule-declaration:
1281/// module-declaration
1282/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001283void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001284 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001285 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1286 if (Tok.is(MMToken::ExternKeyword)) {
1287 parseExternModuleDecl();
1288 return;
1289 }
1290
Douglas Gregorf2161a72011-12-06 17:16:41 +00001291 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001292 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001293 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001294 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001295
Douglas Gregorf2161a72011-12-06 17:16:41 +00001296 // Parse 'explicit' keyword, if present.
1297 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001298 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001299 Explicit = true;
1300 }
1301
1302 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001303 if (Tok.is(MMToken::FrameworkKeyword)) {
1304 consumeToken();
1305 Framework = true;
1306 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001307
1308 // Parse 'module' keyword.
1309 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001310 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001311 consumeToken();
1312 HadError = true;
1313 return;
1314 }
1315 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001316
1317 // If we have a wildcard for the module name, this is an inferred submodule.
1318 // Parse it.
1319 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001320 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001321
1322 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001323 ModuleId Id;
1324 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001325 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001326 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001327 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001328
Douglas Gregore7ab3662011-12-07 02:23:45 +00001329 if (ActiveModule) {
1330 if (Id.size() > 1) {
1331 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1332 << SourceRange(Id.front().second, Id.back().second);
1333
1334 HadError = true;
1335 return;
1336 }
1337 } else if (Id.size() == 1 && Explicit) {
1338 // Top-level modules can't be explicit.
1339 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1340 Explicit = false;
1341 ExplicitLoc = SourceLocation();
1342 HadError = true;
1343 }
1344
1345 Module *PreviousActiveModule = ActiveModule;
1346 if (Id.size() > 1) {
1347 // This module map defines a submodule. Go find the module of which it
1348 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001349 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001350 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001351 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1352 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001353 if (I == 0)
1354 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001355 ActiveModule = Next;
1356 continue;
1357 }
1358
1359 if (ActiveModule) {
1360 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001361 << Id[I].first
1362 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001363 } else {
1364 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1365 }
1366 HadError = true;
1367 return;
1368 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001369
1370 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1371 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1372 "submodule defined in same file as 'module *' that allowed its "
1373 "top-level module");
1374 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1375 }
1376 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001377
1378 StringRef ModuleName = Id.back().first;
1379 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001380
Douglas Gregora686e1b2012-01-27 19:52:33 +00001381 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001382 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001383 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001384
Douglas Gregor718292f2011-11-11 19:10:28 +00001385 // Parse the opening brace.
1386 if (!Tok.is(MMToken::LBrace)) {
1387 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1388 << ModuleName;
1389 HadError = true;
1390 return;
1391 }
1392 SourceLocation LBraceLoc = consumeToken();
1393
1394 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001395 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001396 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1397 // Skip the module definition.
1398 skipUntil(MMToken::RBrace);
1399 if (Tok.is(MMToken::RBrace))
1400 consumeToken();
1401 else {
1402 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1403 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1404 HadError = true;
1405 }
1406 return;
1407 }
1408
Douglas Gregor718292f2011-11-11 19:10:28 +00001409 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1410 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001411 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001412
1413 // Skip the module definition.
1414 skipUntil(MMToken::RBrace);
1415 if (Tok.is(MMToken::RBrace))
1416 consumeToken();
1417
1418 HadError = true;
1419 return;
1420 }
1421
1422 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001423 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1424 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001425 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001426 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001427 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001428 if (Attrs.IsExternC)
1429 ActiveModule->IsExternC = true;
1430
Douglas Gregor718292f2011-11-11 19:10:28 +00001431 bool Done = false;
1432 do {
1433 switch (Tok.Kind) {
1434 case MMToken::EndOfFile:
1435 case MMToken::RBrace:
1436 Done = true;
1437 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001438
1439 case MMToken::ConfigMacros:
1440 parseConfigMacros();
1441 break;
1442
Douglas Gregorfb912652013-03-20 21:10:35 +00001443 case MMToken::Conflict:
1444 parseConflict();
1445 break;
1446
Douglas Gregor718292f2011-11-11 19:10:28 +00001447 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001448 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001449 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001450 case MMToken::ModuleKeyword:
1451 parseModuleDecl();
1452 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001453
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001454 case MMToken::ExportKeyword:
1455 parseExportDecl();
1456 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001457
1458 case MMToken::UseKeyword:
1459 parseUseDecl();
1460 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001461
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001462 case MMToken::RequiresKeyword:
1463 parseRequiresDecl();
1464 break;
1465
Douglas Gregor524e33e2011-12-08 19:11:24 +00001466 case MMToken::UmbrellaKeyword: {
1467 SourceLocation UmbrellaLoc = consumeToken();
1468 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001469 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001470 else
1471 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001472 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001473 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001474
Douglas Gregor59527662012-10-15 06:28:11 +00001475 case MMToken::ExcludeKeyword: {
1476 SourceLocation ExcludeLoc = consumeToken();
1477 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001478 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor59527662012-10-15 06:28:11 +00001479 } else {
1480 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1481 << "exclude";
1482 }
1483 break;
1484 }
1485
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001486 case MMToken::PrivateKeyword: {
1487 SourceLocation PrivateLoc = consumeToken();
1488 if (Tok.is(MMToken::HeaderKeyword)) {
1489 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1490 } else {
1491 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1492 << "private";
1493 }
1494 break;
1495 }
1496
Douglas Gregor322f6332011-12-08 18:00:48 +00001497 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001498 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregor718292f2011-11-11 19:10:28 +00001499 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001500
1501 case MMToken::LinkKeyword:
1502 parseLinkDecl();
1503 break;
1504
Douglas Gregor718292f2011-11-11 19:10:28 +00001505 default:
1506 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1507 consumeToken();
1508 break;
1509 }
1510 } while (!Done);
1511
1512 if (Tok.is(MMToken::RBrace))
1513 consumeToken();
1514 else {
1515 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1516 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1517 HadError = true;
1518 }
1519
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001520 // If the active module is a top-level framework, and there are no link
1521 // libraries, automatically link against the framework.
1522 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1523 ActiveModule->LinkLibraries.empty()) {
1524 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1525 }
1526
Ben Langmuirec8c9752014-04-18 22:07:31 +00001527 // If the module meets all requirements but is still unavailable, mark the
1528 // whole tree as unavailable to prevent it from building.
1529 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1530 ActiveModule->Parent) {
1531 ActiveModule->getTopLevelModule()->markUnavailable();
1532 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1533 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1534 }
1535
Douglas Gregore7ab3662011-12-07 02:23:45 +00001536 // We're done parsing this module. Pop back to the previous module.
1537 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001538}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001539
Daniel Jasper97292842013-09-11 07:20:44 +00001540/// \brief Parse an extern module declaration.
1541///
1542/// extern module-declaration:
1543/// 'extern' 'module' module-id string-literal
1544void ModuleMapParser::parseExternModuleDecl() {
1545 assert(Tok.is(MMToken::ExternKeyword));
1546 consumeToken(); // 'extern' keyword
1547
1548 // Parse 'module' keyword.
1549 if (!Tok.is(MMToken::ModuleKeyword)) {
1550 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1551 consumeToken();
1552 HadError = true;
1553 return;
1554 }
1555 consumeToken(); // 'module' keyword
1556
1557 // Parse the module name.
1558 ModuleId Id;
1559 if (parseModuleId(Id)) {
1560 HadError = true;
1561 return;
1562 }
1563
1564 // Parse the referenced module map file name.
1565 if (!Tok.is(MMToken::StringLiteral)) {
1566 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1567 HadError = true;
1568 return;
1569 }
1570 std::string FileName = Tok.getString();
1571 consumeToken(); // filename
1572
1573 StringRef FileNameRef = FileName;
1574 SmallString<128> ModuleMapFileName;
1575 if (llvm::sys::path::is_relative(FileNameRef)) {
1576 ModuleMapFileName += Directory->getName();
1577 llvm::sys::path::append(ModuleMapFileName, FileName);
1578 FileNameRef = ModuleMapFileName.str();
1579 }
1580 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1581 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1582}
1583
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001584/// \brief Parse a requires declaration.
1585///
1586/// requires-declaration:
1587/// 'requires' feature-list
1588///
1589/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001590/// feature ',' feature-list
1591/// feature
1592///
1593/// feature:
1594/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001595void ModuleMapParser::parseRequiresDecl() {
1596 assert(Tok.is(MMToken::RequiresKeyword));
1597
1598 // Parse 'requires' keyword.
1599 consumeToken();
1600
1601 // Parse the feature-list.
1602 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001603 bool RequiredState = true;
1604 if (Tok.is(MMToken::Exclaim)) {
1605 RequiredState = false;
1606 consumeToken();
1607 }
1608
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001609 if (!Tok.is(MMToken::Identifier)) {
1610 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1611 HadError = true;
1612 return;
1613 }
1614
1615 // Consume the feature name.
1616 std::string Feature = Tok.getString();
1617 consumeToken();
1618
1619 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001620 ActiveModule->addRequirement(Feature, RequiredState,
1621 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001622
1623 if (!Tok.is(MMToken::Comma))
1624 break;
1625
1626 // Consume the comma.
1627 consumeToken();
1628 } while (true);
1629}
1630
Douglas Gregorf2161a72011-12-06 17:16:41 +00001631/// \brief Append to \p Paths the set of paths needed to get to the
1632/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001633static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001634 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001635 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001636 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001637 for (; Mod; Mod = Mod->Parent) {
1638 if (Mod->IsFramework)
1639 Paths.push_back(Mod->Name);
1640 }
1641
1642 if (Paths.empty())
1643 return;
1644
1645 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001646 for (unsigned I = Paths.size() - 1; I != 0; --I)
1647 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001648}
1649
Douglas Gregor718292f2011-11-11 19:10:28 +00001650/// \brief Parse a header declaration.
1651///
1652/// header-declaration:
Douglas Gregor322f6332011-12-08 18:00:48 +00001653/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor59527662012-10-15 06:28:11 +00001654/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001655void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1656 SourceLocation LeadingLoc) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001657 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001658 consumeToken();
1659
Douglas Gregor718292f2011-11-11 19:10:28 +00001660 // Parse the header name.
1661 if (!Tok.is(MMToken::StringLiteral)) {
1662 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1663 << "header";
1664 HadError = true;
1665 return;
1666 }
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001667 Module::HeaderDirective Header;
1668 Header.FileName = Tok.getString();
1669 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001670
Douglas Gregor524e33e2011-12-08 19:11:24 +00001671 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001672 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001673 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001674 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001675 HadError = true;
1676 return;
1677 }
1678
Douglas Gregor5257fc62011-11-11 21:55:48 +00001679 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001680 const FileEntry *File = nullptr;
1681 const FileEntry *BuiltinFile = nullptr;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001682 SmallString<128> PathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001683 if (llvm::sys::path::is_absolute(Header.FileName)) {
1684 PathName = Header.FileName;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001685 File = SourceMgr.getFileManager().getFile(PathName);
1686 } else {
1687 // Search for the header file within the search directory.
Douglas Gregor70331272011-12-09 02:04:43 +00001688 PathName = Directory->getName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001689 unsigned PathLength = PathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001690
Douglas Gregorf2161a72011-12-06 17:16:41 +00001691 if (ActiveModule->isPartOfFramework()) {
1692 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001693
1694 // Check whether this file is in the public headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001695 llvm::sys::path::append(PathName, "Headers", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001696 File = SourceMgr.getFileManager().getFile(PathName);
1697
1698 if (!File) {
1699 // Check whether this file is in the private headers.
1700 PathName.resize(PathLength);
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001701 llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001702 File = SourceMgr.getFileManager().getFile(PathName);
1703 }
1704 } else {
1705 // Lookup for normal headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001706 llvm::sys::path::append(PathName, Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001707 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001708
1709 // If this is a system module with a top-level header, this header
1710 // may have a counterpart (or replacement) in the set of headers
1711 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001712 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1713 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001714 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001715 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001716 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001717 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1718
1719 // If Clang supplies this header but the underlying system does not,
1720 // just silently swap in our builtin version. Otherwise, we'll end
1721 // up adding both (later).
1722 if (!File && BuiltinFile) {
1723 File = BuiltinFile;
Craig Topperd2d442c2014-05-17 23:10:59 +00001724 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001725 }
1726 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001727 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001728 }
Douglas Gregor755b2052011-11-17 22:09:43 +00001729
Douglas Gregor5257fc62011-11-11 21:55:48 +00001730 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1731 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001732 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001733 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001734 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001735 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001736 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001737 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001738 HadError = true;
1739 } else {
1740 // Record this umbrella header.
1741 Map.setUmbrellaHeader(ActiveModule, File);
1742 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00001743 } else {
Douglas Gregor322f6332011-12-08 18:00:48 +00001744 // Record this header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001745 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1746 if (LeadingToken == MMToken::ExcludeKeyword)
1747 Role = ModuleMap::ExcludedHeader;
1748 else if (LeadingToken == MMToken::PrivateKeyword)
1749 Role = ModuleMap::PrivateHeader;
1750 else
1751 assert(LeadingToken == MMToken::HeaderKeyword);
1752
1753 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001754
1755 // If there is a builtin counterpart to this file, add it now.
1756 if (BuiltinFile)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001757 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001758 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001759 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001760 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001761
1762 // If we find a module that has a missing header, we mark this module as
1763 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001764 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001765 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001766 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001767 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001768}
1769
Douglas Gregor524e33e2011-12-08 19:11:24 +00001770/// \brief Parse an umbrella directory declaration.
1771///
1772/// umbrella-dir-declaration:
1773/// umbrella string-literal
1774void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1775 // Parse the directory name.
1776 if (!Tok.is(MMToken::StringLiteral)) {
1777 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1778 << "umbrella";
1779 HadError = true;
1780 return;
1781 }
1782
1783 std::string DirName = Tok.getString();
1784 SourceLocation DirNameLoc = consumeToken();
1785
1786 // Check whether we already have an umbrella.
1787 if (ActiveModule->Umbrella) {
1788 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1789 << ActiveModule->getFullModuleName();
1790 HadError = true;
1791 return;
1792 }
1793
1794 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001795 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001796 if (llvm::sys::path::is_absolute(DirName))
1797 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1798 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001799 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001800 PathName = Directory->getName();
1801 llvm::sys::path::append(PathName, DirName);
1802 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1803 }
1804
1805 if (!Dir) {
1806 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1807 << DirName;
1808 HadError = true;
1809 return;
1810 }
1811
1812 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1813 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1814 << OwningModule->getFullModuleName();
1815 HadError = true;
1816 return;
1817 }
1818
1819 // Record this umbrella directory.
1820 Map.setUmbrellaDir(ActiveModule, Dir);
1821}
1822
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001823/// \brief Parse a module export declaration.
1824///
1825/// export-declaration:
1826/// 'export' wildcard-module-id
1827///
1828/// wildcard-module-id:
1829/// identifier
1830/// '*'
1831/// identifier '.' wildcard-module-id
1832void ModuleMapParser::parseExportDecl() {
1833 assert(Tok.is(MMToken::ExportKeyword));
1834 SourceLocation ExportLoc = consumeToken();
1835
1836 // Parse the module-id with an optional wildcard at the end.
1837 ModuleId ParsedModuleId;
1838 bool Wildcard = false;
1839 do {
1840 if (Tok.is(MMToken::Identifier)) {
1841 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1842 Tok.getLocation()));
1843 consumeToken();
1844
1845 if (Tok.is(MMToken::Period)) {
1846 consumeToken();
1847 continue;
1848 }
1849
1850 break;
1851 }
1852
1853 if(Tok.is(MMToken::Star)) {
1854 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001855 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001856 break;
1857 }
1858
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001859 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001860 HadError = true;
1861 return;
1862 } while (true);
1863
1864 Module::UnresolvedExportDecl Unresolved = {
1865 ExportLoc, ParsedModuleId, Wildcard
1866 };
1867 ActiveModule->UnresolvedExports.push_back(Unresolved);
1868}
1869
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001870/// \brief Parse a module uses declaration.
1871///
1872/// uses-declaration:
1873/// 'uses' wildcard-module-id
1874void ModuleMapParser::parseUseDecl() {
1875 assert(Tok.is(MMToken::UseKeyword));
1876 consumeToken();
1877 // Parse the module-id.
1878 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001879 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001880
1881 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1882}
1883
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001884/// \brief Parse a link declaration.
1885///
1886/// module-declaration:
1887/// 'link' 'framework'[opt] string-literal
1888void ModuleMapParser::parseLinkDecl() {
1889 assert(Tok.is(MMToken::LinkKeyword));
1890 SourceLocation LinkLoc = consumeToken();
1891
1892 // Parse the optional 'framework' keyword.
1893 bool IsFramework = false;
1894 if (Tok.is(MMToken::FrameworkKeyword)) {
1895 consumeToken();
1896 IsFramework = true;
1897 }
1898
1899 // Parse the library name
1900 if (!Tok.is(MMToken::StringLiteral)) {
1901 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1902 << IsFramework << SourceRange(LinkLoc);
1903 HadError = true;
1904 return;
1905 }
1906
1907 std::string LibraryName = Tok.getString();
1908 consumeToken();
1909 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1910 IsFramework));
1911}
1912
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001913/// \brief Parse a configuration macro declaration.
1914///
1915/// module-declaration:
1916/// 'config_macros' attributes[opt] config-macro-list?
1917///
1918/// config-macro-list:
1919/// identifier (',' identifier)?
1920void ModuleMapParser::parseConfigMacros() {
1921 assert(Tok.is(MMToken::ConfigMacros));
1922 SourceLocation ConfigMacrosLoc = consumeToken();
1923
1924 // Only top-level modules can have configuration macros.
1925 if (ActiveModule->Parent) {
1926 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1927 }
1928
1929 // Parse the optional attributes.
1930 Attributes Attrs;
1931 parseOptionalAttributes(Attrs);
1932 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1933 ActiveModule->ConfigMacrosExhaustive = true;
1934 }
1935
1936 // If we don't have an identifier, we're done.
1937 if (!Tok.is(MMToken::Identifier))
1938 return;
1939
1940 // Consume the first identifier.
1941 if (!ActiveModule->Parent) {
1942 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1943 }
1944 consumeToken();
1945
1946 do {
1947 // If there's a comma, consume it.
1948 if (!Tok.is(MMToken::Comma))
1949 break;
1950 consumeToken();
1951
1952 // We expect to see a macro name here.
1953 if (!Tok.is(MMToken::Identifier)) {
1954 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1955 break;
1956 }
1957
1958 // Consume the macro name.
1959 if (!ActiveModule->Parent) {
1960 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1961 }
1962 consumeToken();
1963 } while (true);
1964}
1965
Douglas Gregorfb912652013-03-20 21:10:35 +00001966/// \brief Format a module-id into a string.
1967static std::string formatModuleId(const ModuleId &Id) {
1968 std::string result;
1969 {
1970 llvm::raw_string_ostream OS(result);
1971
1972 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1973 if (I)
1974 OS << ".";
1975 OS << Id[I].first;
1976 }
1977 }
1978
1979 return result;
1980}
1981
1982/// \brief Parse a conflict declaration.
1983///
1984/// module-declaration:
1985/// 'conflict' module-id ',' string-literal
1986void ModuleMapParser::parseConflict() {
1987 assert(Tok.is(MMToken::Conflict));
1988 SourceLocation ConflictLoc = consumeToken();
1989 Module::UnresolvedConflict Conflict;
1990
1991 // Parse the module-id.
1992 if (parseModuleId(Conflict.Id))
1993 return;
1994
1995 // Parse the ','.
1996 if (!Tok.is(MMToken::Comma)) {
1997 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1998 << SourceRange(ConflictLoc);
1999 return;
2000 }
2001 consumeToken();
2002
2003 // Parse the message.
2004 if (!Tok.is(MMToken::StringLiteral)) {
2005 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2006 << formatModuleId(Conflict.Id);
2007 return;
2008 }
2009 Conflict.Message = Tok.getString().str();
2010 consumeToken();
2011
2012 // Add this unresolved conflict.
2013 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2014}
2015
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002016/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002017///
2018/// module-declaration:
2019/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2020/// { inferred-module-member* }
2021///
2022/// inferred-module-member:
2023/// 'export' '*'
2024/// 'exclude' identifier
2025void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002026 assert(Tok.is(MMToken::Star));
2027 SourceLocation StarLoc = consumeToken();
2028 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002029
Douglas Gregor73441092011-12-05 22:27:44 +00002030 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002031 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002032 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2033 Failed = true;
2034 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002035
2036 if (ActiveModule) {
2037 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002038 if (!Failed && ActiveModule->IsAvailable &&
2039 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002040 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2041 Failed = true;
2042 }
2043
2044 // Check for redefinition of an inferred module.
2045 if (!Failed && ActiveModule->InferSubmodules) {
2046 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2047 if (ActiveModule->InferredSubmoduleLoc.isValid())
2048 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2049 diag::note_mmap_prev_definition);
2050 Failed = true;
2051 }
2052
2053 // Check for the 'framework' keyword, which is not permitted here.
2054 if (Framework) {
2055 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2056 Framework = false;
2057 }
2058 } else if (Explicit) {
2059 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2060 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002061 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002062
Douglas Gregor73441092011-12-05 22:27:44 +00002063 // If there were any problems with this inferred submodule, skip its body.
2064 if (Failed) {
2065 if (Tok.is(MMToken::LBrace)) {
2066 consumeToken();
2067 skipUntil(MMToken::RBrace);
2068 if (Tok.is(MMToken::RBrace))
2069 consumeToken();
2070 }
2071 HadError = true;
2072 return;
2073 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002074
2075 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002076 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002077 parseOptionalAttributes(Attrs);
2078
2079 if (ActiveModule) {
2080 // Note that we have an inferred submodule.
2081 ActiveModule->InferSubmodules = true;
2082 ActiveModule->InferredSubmoduleLoc = StarLoc;
2083 ActiveModule->InferExplicitSubmodules = Explicit;
2084 } else {
2085 // We'll be inferring framework modules for this directory.
2086 Map.InferredDirectories[Directory].InferModules = true;
2087 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002088 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002089 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002090 }
2091
Douglas Gregor73441092011-12-05 22:27:44 +00002092 // Parse the opening brace.
2093 if (!Tok.is(MMToken::LBrace)) {
2094 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2095 HadError = true;
2096 return;
2097 }
2098 SourceLocation LBraceLoc = consumeToken();
2099
2100 // Parse the body of the inferred submodule.
2101 bool Done = false;
2102 do {
2103 switch (Tok.Kind) {
2104 case MMToken::EndOfFile:
2105 case MMToken::RBrace:
2106 Done = true;
2107 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002108
2109 case MMToken::ExcludeKeyword: {
2110 if (ActiveModule) {
2111 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002112 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002113 consumeToken();
2114 break;
2115 }
2116
2117 consumeToken();
2118 if (!Tok.is(MMToken::Identifier)) {
2119 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2120 break;
2121 }
2122
2123 Map.InferredDirectories[Directory].ExcludedModules
2124 .push_back(Tok.getString());
2125 consumeToken();
2126 break;
2127 }
2128
2129 case MMToken::ExportKeyword:
2130 if (!ActiveModule) {
2131 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002132 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002133 consumeToken();
2134 break;
2135 }
2136
Douglas Gregor73441092011-12-05 22:27:44 +00002137 consumeToken();
2138 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002139 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002140 else
2141 Diags.Report(Tok.getLocation(),
2142 diag::err_mmap_expected_export_wildcard);
2143 consumeToken();
2144 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002145
Douglas Gregor73441092011-12-05 22:27:44 +00002146 case MMToken::ExplicitKeyword:
2147 case MMToken::ModuleKeyword:
2148 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002149 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002150 case MMToken::UmbrellaKeyword:
2151 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002152 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002153 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002154 consumeToken();
2155 break;
2156 }
2157 } while (!Done);
2158
2159 if (Tok.is(MMToken::RBrace))
2160 consumeToken();
2161 else {
2162 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2163 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2164 HadError = true;
2165 }
2166}
2167
Douglas Gregor9194a912012-11-06 19:39:40 +00002168/// \brief Parse optional attributes.
2169///
2170/// attributes:
2171/// attribute attributes
2172/// attribute
2173///
2174/// attribute:
2175/// [ identifier ]
2176///
2177/// \param Attrs Will be filled in with the parsed attributes.
2178///
2179/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002180bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002181 bool HadError = false;
2182
2183 while (Tok.is(MMToken::LSquare)) {
2184 // Consume the '['.
2185 SourceLocation LSquareLoc = consumeToken();
2186
2187 // Check whether we have an attribute name here.
2188 if (!Tok.is(MMToken::Identifier)) {
2189 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2190 skipUntil(MMToken::RSquare);
2191 if (Tok.is(MMToken::RSquare))
2192 consumeToken();
2193 HadError = true;
2194 }
2195
2196 // Decode the attribute name.
2197 AttributeKind Attribute
2198 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002199 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002200 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002201 .Case("system", AT_system)
2202 .Default(AT_unknown);
2203 switch (Attribute) {
2204 case AT_unknown:
2205 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2206 << Tok.getString();
2207 break;
2208
2209 case AT_system:
2210 Attrs.IsSystem = true;
2211 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002212
Richard Smith77944862014-03-02 05:58:18 +00002213 case AT_extern_c:
2214 Attrs.IsExternC = true;
2215 break;
2216
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002217 case AT_exhaustive:
2218 Attrs.IsExhaustive = true;
2219 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002220 }
2221 consumeToken();
2222
2223 // Consume the ']'.
2224 if (!Tok.is(MMToken::RSquare)) {
2225 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2226 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2227 skipUntil(MMToken::RSquare);
2228 HadError = true;
2229 }
2230
2231 if (Tok.is(MMToken::RSquare))
2232 consumeToken();
2233 }
2234
2235 return HadError;
2236}
2237
Douglas Gregor718292f2011-11-11 19:10:28 +00002238/// \brief Parse a module map file.
2239///
2240/// module-map-file:
2241/// module-declaration*
2242bool ModuleMapParser::parseModuleMapFile() {
2243 do {
2244 switch (Tok.Kind) {
2245 case MMToken::EndOfFile:
2246 return HadError;
2247
Douglas Gregore7ab3662011-12-07 02:23:45 +00002248 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002249 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002250 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002251 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002252 parseModuleDecl();
2253 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002254
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002255 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002256 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002257 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002258 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002259 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002260 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002261 case MMToken::HeaderKeyword:
2262 case MMToken::Identifier:
2263 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002264 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002265 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002266 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002267 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002268 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002269 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002270 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002271 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002272 case MMToken::StringLiteral:
2273 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002274 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002275 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2276 HadError = true;
2277 consumeToken();
2278 break;
2279 }
2280 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002281}
2282
Douglas Gregor963c5532013-06-21 16:28:10 +00002283bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002284 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2285 = ParsedModuleMap.find(File);
2286 if (Known != ParsedModuleMap.end())
2287 return Known->second;
2288
Craig Topperd2d442c2014-05-17 23:10:59 +00002289 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002290 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2291 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002292 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002293 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002294 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002295
2296 // Find the directory for the module. For frameworks, that may require going
2297 // up from the 'Modules' directory.
2298 const DirectoryEntry *Dir = File->getDir();
2299 StringRef DirName(Dir->getName());
2300 if (llvm::sys::path::filename(DirName) == "Modules") {
2301 DirName = llvm::sys::path::parent_path(DirName);
2302 if (DirName.endswith(".framework"))
2303 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2304 assert(Dir && "parent must exist");
2305 }
Douglas Gregor718292f2011-11-11 19:10:28 +00002306
2307 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002308 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002309 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002310 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002311 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002312 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002313 return Result;
2314}