blob: 9ac554ae96c3a41d010a6ec8967ab88af7d0bc38 [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
Richard Smith202210b2014-10-24 20:23:01 +0000205// Returns true if RequestingModule directly uses RequestedModule.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000206static 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) {
Richard Smith202210b2014-10-24 20:23:01 +0000217 bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
218#ifndef NDEBUG
Daniel Jasper92669ee2013-12-20 12:09:36 +0000219 // Check for consistency between the module header role
220 // as obtained from the lookup and as obtained from the module.
221 // This check is not cheap, so enable it only for debugging.
Richard Smith202210b2014-10-24 20:23:01 +0000222 bool IsPrivate = false;
Richard Smith3c1a41a2014-12-02 00:08:08 +0000223 SmallVectorImpl<Module::Header> *HeaderList[] =
224 {&RequestedModule->Headers[Module::HK_Private],
225 &RequestedModule->Headers[Module::HK_PrivateTextual]};
Hans Wennborg0ef0aec2014-10-26 19:39:46 +0000226 for (auto *Hdrs : HeaderList)
Richard Smith202210b2014-10-24 20:23:01 +0000227 IsPrivate |=
Richard Smith3c1a41a2014-12-02 00:08:08 +0000228 std::find_if(Hdrs->begin(), Hdrs->end(), [&](const Module::Header &H) {
229 return H.Entry == IncFileEnt;
230 }) != Hdrs->end();
Richard Smith202210b2014-10-24 20:23:01 +0000231 assert(IsPrivate == IsPrivateRole && "inconsistent headers and roles");
232#endif
233 return IsPrivateRole &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000234 RequestedModule->getTopLevelModule() != RequestingModule;
235}
236
Ben Langmuir71e1a642014-05-05 21:44:13 +0000237static Module *getTopLevelOrNull(Module *M) {
238 return M ? M->getTopLevelModule() : nullptr;
239}
240
Daniel Jasper92669ee2013-12-20 12:09:36 +0000241void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
242 SourceLocation FilenameLoc,
243 StringRef Filename,
244 const FileEntry *File) {
245 // No errors for indirect modules. This may be a bit of a problem for modules
246 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000247 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000248 return;
249
250 if (RequestingModule)
251 resolveUses(RequestingModule, /*Complain=*/false);
252
Ben Langmuir71e1a642014-05-05 21:44:13 +0000253 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000254 Module *Private = nullptr;
255 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000256
Ben Langmuir71e1a642014-05-05 21:44:13 +0000257 HeadersMap::iterator Known = findKnownHeader(File);
258 if (Known != Headers.end()) {
259 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000260 // If 'File' is part of 'RequestingModule' we can definitely include it.
261 if (Header.getModule() == RequestingModule)
262 return;
263
264 // Remember private headers for later printing of a diagnostic.
265 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
266 Header.getModule())) {
267 Private = Header.getModule();
268 continue;
269 }
270
271 // If uses need to be specified explicitly, we are only allowed to return
272 // modules that are explicitly used by the requesting module.
273 if (RequestingModule && LangOpts.ModulesDeclUse &&
274 !directlyUses(RequestingModule, Header.getModule())) {
275 NotUsed = Header.getModule();
276 continue;
277 }
278
279 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000280 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000281 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000282
283 Excluded = true;
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,
Richard Smith306d8922014-10-22 23:50:56 +0000318 Module *RequestingModule,
319 bool IncludeTextualHeaders) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000320 HeadersMap::iterator Known = findKnownHeader(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000321
Richard Smith306d8922014-10-22 23:50:56 +0000322 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Richard Smith202210b2014-10-24 20:23:01 +0000323 if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader))
Richard Smith306d8922014-10-22 23:50:56 +0000324 return ModuleMap::KnownHeader();
325 return R;
326 };
327
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000328 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000329 ModuleMap::KnownHeader Result;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000330
Daniel Jasper97da9172013-10-22 08:09:47 +0000331 // Iterate over all modules that 'File' is part of to find the best fit.
332 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
333 E = Known->second.end();
334 I != E; ++I) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000335 // Cannot use a module if it is unavailable.
336 if (!I->getModule()->isAvailable())
Daniel Jasper97da9172013-10-22 08:09:47 +0000337 continue;
338
339 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
340 // module we are looking for.
341 if (I->getModule() == RequestingModule)
Richard Smith306d8922014-10-22 23:50:56 +0000342 return MakeResult(*I);
Daniel Jasper97da9172013-10-22 08:09:47 +0000343
344 // If uses need to be specified explicitly, we are only allowed to return
345 // modules that are explicitly used by the requesting module.
346 if (RequestingModule && LangOpts.ModulesDeclUse &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000347 !directlyUses(RequestingModule, I->getModule()))
Daniel Jasper97da9172013-10-22 08:09:47 +0000348 continue;
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000349
Richard Smith202210b2014-10-24 20:23:01 +0000350 // Prefer a public header over a private header.
351 if (!Result || (Result.getRole() & ModuleMap::PrivateHeader))
352 Result = *I;
Daniel Jasper97da9172013-10-22 08:09:47 +0000353 }
Richard Smith306d8922014-10-22 23:50:56 +0000354 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000355 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000356
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000357 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000358 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
359 if (H) {
360 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000361
Ben Langmuir44691382014-04-10 00:39:10 +0000362 // Search up the module stack until we find a module with an umbrella
363 // directory.
364 Module *UmbrellaModule = Result;
365 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
366 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000367
Ben Langmuir44691382014-04-10 00:39:10 +0000368 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000369 const FileEntry *UmbrellaModuleMap =
370 getModuleMapFileForUniquing(UmbrellaModule);
371
Ben Langmuir44691382014-04-10 00:39:10 +0000372 // Infer submodules for each of the directories we found between
373 // the directory of the umbrella header and the directory where
374 // the actual header is located.
375 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000376
Ben Langmuir44691382014-04-10 00:39:10 +0000377 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
378 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000379 SmallString<32> NameBuf;
380 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000381 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000382 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
383 Explicit).first;
384 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000385 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000386
387 // Associate the module and the directory.
388 UmbrellaDirs[SkippedDirs[I-1]] = Result;
389
390 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000391 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000392 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000393 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000394 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000395
Ben Langmuir44691382014-04-10 00:39:10 +0000396 // Infer a submodule with the same name as this header file.
397 SmallString<32> NameBuf;
398 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000399 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000400 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
401 Explicit).first;
402 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000403 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000404 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000405
Ben Langmuir44691382014-04-10 00:39:10 +0000406 // If inferred submodules export everything they import, add a
407 // wildcard to the set of exports.
408 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000409 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000410 } else {
411 // Record each of the directories we stepped through as being part of
412 // the module we found, since the umbrella header covers them all.
413 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
414 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000415 }
Ben Langmuir44691382014-04-10 00:39:10 +0000416
417 Headers[File].push_back(KnownHeader(Result, NormalHeader));
418
419 // If a header corresponds to an unavailable module, don't report
420 // that it maps to anything.
421 if (!Result->isAvailable())
422 return KnownHeader();
423
Richard Smith306d8922014-10-22 23:50:56 +0000424 return MakeResult(Headers[File].back());
Ben Langmuir44691382014-04-10 00:39:10 +0000425 }
Richard Smith306d8922014-10-22 23:50:56 +0000426
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000427 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000428}
429
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000430bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000431 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000432}
433
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000434bool
435ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
436 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000437 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000438 if (Known != Headers.end()) {
439 for (SmallVectorImpl<KnownHeader>::const_iterator
440 I = Known->second.begin(),
441 E = Known->second.end();
442 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000443 if (I->isAvailable() && (!RequestingModule ||
444 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000445 return false;
446 }
447 return true;
448 }
Richard Smith50996ce2014-04-08 13:13:04 +0000449
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000450 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000451 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000452 StringRef DirName = Dir->getName();
453
Richard Smith50996ce2014-04-08 13:13:04 +0000454 auto IsUnavailable = [&](const Module *M) {
455 return !M->isAvailable() && (!RequestingModule ||
456 M->isSubModuleOf(RequestingModule));
457 };
458
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000459 // Keep walking up the directory hierarchy, looking for a directory with
460 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000461 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000462 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000463 = UmbrellaDirs.find(Dir);
464 if (KnownDir != UmbrellaDirs.end()) {
465 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000466 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000467 return true;
468
469 // Search up the module stack until we find a module with an umbrella
470 // directory.
471 Module *UmbrellaModule = Found;
472 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
473 UmbrellaModule = UmbrellaModule->Parent;
474
475 if (UmbrellaModule->InferSubmodules) {
476 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
477 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000478 SmallString<32> NameBuf;
479 StringRef Name = sanitizeFilenameAsIdentifier(
480 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
481 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000482 Found = lookupModuleQualified(Name, Found);
483 if (!Found)
484 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000485 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000486 return true;
487 }
488
489 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000490 SmallString<32> NameBuf;
491 StringRef Name = sanitizeFilenameAsIdentifier(
492 llvm::sys::path::stem(Header->getName()),
493 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000494 Found = lookupModuleQualified(Name, Found);
495 if (!Found)
496 return false;
497 }
498
Richard Smith50996ce2014-04-08 13:13:04 +0000499 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000500 }
501
502 SkippedDirs.push_back(Dir);
503
504 // Retrieve our parent path.
505 DirName = llvm::sys::path::parent_path(DirName);
506 if (DirName.empty())
507 break;
508
509 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000510 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000511 } while (Dir);
512
513 return false;
514}
515
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000516Module *ModuleMap::findModule(StringRef Name) const {
517 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000518 if (Known != Modules.end())
519 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000520
521 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000522}
523
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000524Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
525 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000526 for(; Context; Context = Context->Parent) {
527 if (Module *Sub = lookupModuleQualified(Name, Context))
528 return Sub;
529 }
530
531 return findModule(Name);
532}
533
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000534Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000535 if (!Context)
536 return findModule(Name);
537
Douglas Gregoreb90e832012-01-04 23:32:19 +0000538 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000539}
540
Douglas Gregorde3ef502011-11-30 23:21:26 +0000541std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000542ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000543 bool IsExplicit) {
544 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000545 if (Module *Sub = lookupModuleQualified(Name, Parent))
546 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000547
548 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000549 Module *Result = new Module(Name, SourceLocation(), Parent,
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000550 IsFramework, IsExplicit);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000551 if (LangOpts.CurrentModule == Name) {
552 SourceModule = Result;
553 SourceModuleName = Name;
554 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000555 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000556 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000557 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
558 Name == LangOpts.CurrentModule) {
559 CompilingModule = Result;
560 }
561 }
Douglas Gregor69021972011-11-30 17:33:56 +0000562 return std::make_pair(Result, true);
563}
564
Douglas Gregor9194a912012-11-06 19:39:40 +0000565bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000566 StringRef Name, bool &IsSystem) const {
Douglas Gregor9194a912012-11-06 19:39:40 +0000567 // Check whether we have already looked into the parent directory
568 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000569 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000570 inferred = InferredDirectories.find(ParentDir);
571 if (inferred == InferredDirectories.end())
572 return false;
573
574 if (!inferred->second.InferModules)
575 return false;
576
577 // We're allowed to infer for this directory, but make sure it's okay
578 // to infer this particular module.
579 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
580 inferred->second.ExcludedModules.end(),
581 Name) == inferred->second.ExcludedModules.end();
582
583 if (canInfer && inferred->second.InferSystemModules)
584 IsSystem = true;
585
586 return canInfer;
587}
588
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000589/// \brief For a framework module, infer the framework against which we
590/// should link.
591static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
592 FileManager &FileMgr) {
593 assert(Mod->IsFramework && "Can only infer linking for framework modules");
594 assert(!Mod->isSubFramework() &&
595 "Can only infer linking for top-level frameworks");
596
597 SmallString<128> LibName;
598 LibName += FrameworkDir->getName();
599 llvm::sys::path::append(LibName, Mod->Name);
600 if (FileMgr.getFile(LibName)) {
601 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
602 /*IsFramework=*/true));
603 }
604}
605
Douglas Gregorde3ef502011-11-30 23:21:26 +0000606Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000607ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000608 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000609 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000610 Module *Parent) {
Douglas Gregor56c64012011-11-17 01:41:17 +0000611 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000612 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
613 return Mod;
614
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000615 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000616
617 // If the framework has a parent path from which we're allowed to infer
618 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000619 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000620 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000621 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000622
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000623 // Note: as an egregious but useful hack we use the real path here, because
624 // we might be looking at an embedded framework that symlinks out to a
625 // top-level framework, and we need to infer as if we were naming the
626 // top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000627 StringRef FrameworkDirName
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000628 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000629
Ben Langmuir6b7f7342014-07-14 19:45:12 +0000630 // In case this is a case-insensitive filesystem, make sure the canonical
631 // directory name matches ModuleName exactly. Modules are case-sensitive.
632 // FIXME: we should be able to give a fix-it hint for the correct spelling.
633 if (llvm::sys::path::stem(FrameworkDirName) != ModuleName)
634 return nullptr;
635
Douglas Gregor9194a912012-11-06 19:39:40 +0000636 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000637 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000638 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000639 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000640 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
641 // Check whether we have already looked into the parent directory
642 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000643 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000644 inferred = InferredDirectories.find(ParentDir);
645 if (inferred == InferredDirectories.end()) {
646 // We haven't looked here before. Load a module map, if there is
647 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000648 bool IsFrameworkDir = Parent.endswith(".framework");
649 if (const FileEntry *ModMapFile =
650 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Duncan P. N. Exon Smith00a4da72014-12-09 06:35:37 +0000651 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor9194a912012-11-06 19:39:40 +0000652 inferred = InferredDirectories.find(ParentDir);
653 }
654
655 if (inferred == InferredDirectories.end())
656 inferred = InferredDirectories.insert(
657 std::make_pair(ParentDir, InferredDirectory())).first;
658 }
659
660 if (inferred->second.InferModules) {
661 // We're allowed to infer for this directory, but make sure it's okay
662 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000663 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000664 canInfer = std::find(inferred->second.ExcludedModules.begin(),
665 inferred->second.ExcludedModules.end(),
666 Name) == inferred->second.ExcludedModules.end();
667
668 if (inferred->second.InferSystemModules)
669 IsSystem = true;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000670 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000671 }
672 }
673 }
674
675 // If we're not allowed to infer a framework module, don't.
676 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000677 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000678 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000679 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000680
681
Douglas Gregor56c64012011-11-17 01:41:17 +0000682 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000683 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000684 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000685 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000686
687 // FIXME: If there's no umbrella header, we could probably scan the
688 // framework to load *everything*. But, it's not clear that this is a good
689 // idea.
690 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000691 return nullptr;
692
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000693 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000694 /*IsFramework=*/true, /*IsExplicit=*/false);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000695 InferredModuleAllowedBy[Result] = ModuleMapFile;
696 Result->IsInferred = true;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000697 if (LangOpts.CurrentModule == ModuleName) {
698 SourceModule = Result;
699 SourceModuleName = ModuleName;
700 }
Douglas Gregora686e1b2012-01-27 19:52:33 +0000701 if (IsSystem)
702 Result->IsSystem = IsSystem;
703
Douglas Gregoreb90e832012-01-04 23:32:19 +0000704 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000705 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000706
Douglas Gregor322f6332011-12-08 18:00:48 +0000707 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000708 Result->Umbrella = UmbrellaHeader;
Daniel Jasper97da9172013-10-22 08:09:47 +0000709 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor4dc71832011-12-12 23:55:05 +0000710 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000711
712 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000713 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
714
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000715 // module * { export * }
716 Result->InferSubmodules = true;
717 Result->InferExportWildcard = true;
718
Douglas Gregore89dbc12011-12-06 19:39:29 +0000719 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000720 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000721 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000722 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000723 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000724 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000725 for (llvm::sys::fs::directory_iterator
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000726 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000727 Dir != DirEnd && !EC; Dir.increment(EC)) {
728 if (!StringRef(Dir->path()).endswith(".framework"))
729 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000730
Douglas Gregore89dbc12011-12-06 19:39:29 +0000731 if (const DirectoryEntry *SubframeworkDir
732 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000733 // Note: as an egregious but useful hack, we use the real path here and
734 // check whether it is actually a subdirectory of the parent directory.
735 // This will not be the case if the 'subframework' is actually a symlink
736 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000737 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
738 bool FoundParent = false;
739 do {
740 // Get the parent directory name.
741 SubframeworkDirName
742 = llvm::sys::path::parent_path(SubframeworkDirName);
743 if (SubframeworkDirName.empty())
744 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000745
Douglas Gregore00c8b22013-01-26 00:55:12 +0000746 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
747 FoundParent = true;
748 break;
749 }
750 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000751
Douglas Gregore00c8b22013-01-26 00:55:12 +0000752 if (!FoundParent)
753 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000754
Douglas Gregore89dbc12011-12-06 19:39:29 +0000755 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-10-12 21:15:50 +0000756 SmallString<32> NameBuf;
757 inferFrameworkModule(sanitizeFilenameAsIdentifier(
758 llvm::sys::path::stem(Dir->path()), NameBuf),
759 SubframeworkDir, IsSystem, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000760 }
761 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000762
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000763 // If the module is a top-level framework, automatically link against the
764 // framework.
765 if (!Result->isSubFramework()) {
766 inferFrameworkLink(Result, FrameworkDir, FileMgr);
767 }
768
Douglas Gregor56c64012011-11-17 01:41:17 +0000769 return Result;
770}
771
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000772void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasper97da9172013-10-22 08:09:47 +0000773 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000774 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000775 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000776}
777
Douglas Gregor524e33e2011-12-08 19:11:24 +0000778void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
779 Mod->Umbrella = UmbrellaDir;
780 UmbrellaDirs[UmbrellaDir] = Mod;
781}
782
Richard Smith3c1a41a2014-12-02 00:08:08 +0000783static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000784 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000785 default: llvm_unreachable("unknown header role");
786 case ModuleMap::NormalHeader:
787 return Module::HK_Normal;
788 case ModuleMap::PrivateHeader:
789 return Module::HK_Private;
790 case ModuleMap::TextualHeader:
791 return Module::HK_Textual;
792 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
793 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000794 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000795}
796
Richard Smith3c1a41a2014-12-02 00:08:08 +0000797void ModuleMap::addHeader(Module *Mod, Module::Header Header,
798 ModuleHeaderRole Role) {
799 if (!(Role & TextualHeader)) {
800 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
801 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
802 isCompilingModuleHeader);
803 }
804 Headers[Header.Entry].push_back(KnownHeader(Mod, Role));
Richard Smithfeb54b62014-10-23 02:01:19 +0000805
Richard Smith3c1a41a2014-12-02 00:08:08 +0000806 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
807}
808
809void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000810 // Add this as a known header so we won't implicitly add it to any
811 // umbrella directory module.
812 // FIXME: Should we only exclude it from umbrella modules within the
813 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000814 (void) Headers[Header.Entry];
815
816 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000817}
818
Douglas Gregor514b6362011-11-29 19:06:37 +0000819const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000820ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000821 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000822 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000823
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000824 return SourceMgr.getFileEntryForID(
825 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000826}
827
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000828const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000829 if (M->IsInferred) {
830 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
831 return InferredModuleAllowedBy.find(M)->second;
832 }
833 return getContainingModuleMapFile(M);
834}
835
836void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
837 assert(M->IsInferred && "module not inferred");
838 InferredModuleAllowedBy[M] = ModMap;
839}
840
Douglas Gregor718292f2011-11-11 19:10:28 +0000841void ModuleMap::dump() {
842 llvm::errs() << "Modules:";
843 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
844 MEnd = Modules.end();
845 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000846 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000847
848 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000849 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000850 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000851 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
852 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
853 E = H->second.end();
854 I != E; ++I) {
855 if (I != H->second.begin())
856 llvm::errs() << ",";
857 llvm::errs() << I->getModule()->getFullModuleName();
858 }
859 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000860 }
861}
862
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000863bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
864 bool HadError = false;
865 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
866 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
867 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000868 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000869 Mod->Exports.push_back(Export);
870 else
871 HadError = true;
872 }
873 Mod->UnresolvedExports.clear();
874 return HadError;
875}
876
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000877bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
878 bool HadError = false;
879 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
880 Module *DirectUse =
881 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
882 if (DirectUse)
883 Mod->DirectUses.push_back(DirectUse);
884 else
885 HadError = true;
886 }
887 Mod->UnresolvedDirectUses.clear();
888 return HadError;
889}
890
Douglas Gregorfb912652013-03-20 21:10:35 +0000891bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
892 bool HadError = false;
893 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
894 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
895 Mod, Complain);
896 if (!OtherMod) {
897 HadError = true;
898 continue;
899 }
900
901 Module::Conflict Conflict;
902 Conflict.Other = OtherMod;
903 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
904 Mod->Conflicts.push_back(Conflict);
905 }
906 Mod->UnresolvedConflicts.clear();
907 return HadError;
908}
909
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000910Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
911 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000912 return nullptr;
913
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000914 // Use the expansion location to determine which module we're in.
915 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
916 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000917 return nullptr;
918
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000919 const SourceManager &SrcMgr = Loc.getManager();
920 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000921
Douglas Gregor224d8a72012-01-06 17:19:32 +0000922 while (const FileEntry *ExpansionFile
923 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
924 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000925 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000926 return Mod;
927
928 // No module owns this header, so look up the inclusion chain to see if
929 // any included header has an associated module.
930 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
931 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000932 return nullptr;
933
Douglas Gregor224d8a72012-01-06 17:19:32 +0000934 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
935 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000936
937 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000938}
939
Douglas Gregor718292f2011-11-11 19:10:28 +0000940//----------------------------------------------------------------------------//
941// Module map file parser
942//----------------------------------------------------------------------------//
943
944namespace clang {
945 /// \brief A token in a module map file.
946 struct MMToken {
947 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000948 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000949 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000950 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000951 EndOfFile,
952 HeaderKeyword,
953 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000954 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000955 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000956 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000957 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000958 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000959 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000960 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000961 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000962 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000963 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000964 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000965 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000966 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000967 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000968 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000969 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000970 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000971 RBrace,
972 LSquare,
973 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000974 } Kind;
975
976 unsigned Location;
977 unsigned StringLength;
978 const char *StringData;
979
980 void clear() {
981 Kind = EndOfFile;
982 Location = 0;
983 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000984 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000985 }
986
987 bool is(TokenKind K) const { return Kind == K; }
988
989 SourceLocation getLocation() const {
990 return SourceLocation::getFromRawEncoding(Location);
991 }
992
993 StringRef getString() const {
994 return StringRef(StringData, StringLength);
995 }
996 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000997
998 /// \brief The set of attributes that can be attached to a module.
Bill Wendling44426052012-12-20 19:22:21 +0000999 struct Attributes {
Richard Smith77944862014-03-02 05:58:18 +00001000 Attributes() : IsSystem(), IsExternC(), IsExhaustive() { }
Douglas Gregor9194a912012-11-06 19:39:40 +00001001
1002 /// \brief Whether this is a system module.
1003 unsigned IsSystem : 1;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001004
Richard Smith77944862014-03-02 05:58:18 +00001005 /// \brief Whether this is an extern "C" module.
1006 unsigned IsExternC : 1;
1007
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001008 /// \brief Whether this is an exhaustive set of configuration macros.
1009 unsigned IsExhaustive : 1;
Douglas Gregor9194a912012-11-06 19:39:40 +00001010 };
Douglas Gregor718292f2011-11-11 19:10:28 +00001011
Douglas Gregor9194a912012-11-06 19:39:40 +00001012
Douglas Gregor718292f2011-11-11 19:10:28 +00001013 class ModuleMapParser {
1014 Lexer &L;
1015 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001016
1017 /// \brief Default target information, used only for string literal
1018 /// parsing.
1019 const TargetInfo *Target;
1020
Douglas Gregor718292f2011-11-11 19:10:28 +00001021 DiagnosticsEngine &Diags;
1022 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001023
1024 /// \brief The current module map file.
1025 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001026
Duncan P. N. Exon Smith00a4da72014-12-09 06:35:37 +00001027 /// \brief The directory that this module map resides in.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001028 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001029
1030 /// \brief The directory containing Clang-supplied headers.
1031 const DirectoryEntry *BuiltinIncludeDir;
1032
Douglas Gregor963c5532013-06-21 16:28:10 +00001033 /// \brief Whether this module map is in a system header directory.
1034 bool IsSystem;
1035
Douglas Gregor718292f2011-11-11 19:10:28 +00001036 /// \brief Whether an error occurred.
1037 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001038
Douglas Gregor718292f2011-11-11 19:10:28 +00001039 /// \brief Stores string data for the various string literals referenced
1040 /// during parsing.
1041 llvm::BumpPtrAllocator StringData;
1042
1043 /// \brief The current token.
1044 MMToken Tok;
1045
1046 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001047 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001048
1049 /// \brief Consume the current token and return its location.
1050 SourceLocation consumeToken();
1051
1052 /// \brief Skip tokens until we reach the a token with the given kind
1053 /// (or the end of the file).
1054 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001055
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001056 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001057 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001058 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001059 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001060 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001061 void parseHeaderDecl(clang::MMToken::TokenKind,
1062 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001063 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001064 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001065 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001066 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001067 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001068 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001069 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendling44426052012-12-20 19:22:21 +00001070 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001071
Douglas Gregor718292f2011-11-11 19:10:28 +00001072 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001073 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001074 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001075 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001076 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001077 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001078 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001079 const DirectoryEntry *BuiltinIncludeDir,
1080 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001081 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001082 ModuleMapFile(ModuleMapFile), Directory(Directory),
1083 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001084 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001085 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001086 Tok.clear();
1087 consumeToken();
1088 }
1089
1090 bool parseModuleMapFile();
1091 };
1092}
1093
1094SourceLocation ModuleMapParser::consumeToken() {
1095retry:
1096 SourceLocation Result = Tok.getLocation();
1097 Tok.clear();
1098
1099 Token LToken;
1100 L.LexFromRawLexer(LToken);
1101 Tok.Location = LToken.getLocation().getRawEncoding();
1102 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001103 case tok::raw_identifier: {
1104 StringRef RI = LToken.getRawIdentifier();
1105 Tok.StringData = RI.data();
1106 Tok.StringLength = RI.size();
1107 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001108 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001109 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001110 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001111 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001112 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001113 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001114 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001115 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001116 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001117 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001118 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001119 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001120 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001121 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001122 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001123 .Default(MMToken::Identifier);
1124 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001125 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001126
1127 case tok::comma:
1128 Tok.Kind = MMToken::Comma;
1129 break;
1130
Douglas Gregor718292f2011-11-11 19:10:28 +00001131 case tok::eof:
1132 Tok.Kind = MMToken::EndOfFile;
1133 break;
1134
1135 case tok::l_brace:
1136 Tok.Kind = MMToken::LBrace;
1137 break;
1138
Douglas Gregora686e1b2012-01-27 19:52:33 +00001139 case tok::l_square:
1140 Tok.Kind = MMToken::LSquare;
1141 break;
1142
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001143 case tok::period:
1144 Tok.Kind = MMToken::Period;
1145 break;
1146
Douglas Gregor718292f2011-11-11 19:10:28 +00001147 case tok::r_brace:
1148 Tok.Kind = MMToken::RBrace;
1149 break;
1150
Douglas Gregora686e1b2012-01-27 19:52:33 +00001151 case tok::r_square:
1152 Tok.Kind = MMToken::RSquare;
1153 break;
1154
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001155 case tok::star:
1156 Tok.Kind = MMToken::Star;
1157 break;
1158
Richard Smitha3feee22013-10-28 22:18:19 +00001159 case tok::exclaim:
1160 Tok.Kind = MMToken::Exclaim;
1161 break;
1162
Douglas Gregor718292f2011-11-11 19:10:28 +00001163 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001164 if (LToken.hasUDSuffix()) {
1165 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1166 HadError = true;
1167 goto retry;
1168 }
1169
Douglas Gregor718292f2011-11-11 19:10:28 +00001170 // Parse the string literal.
1171 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001172 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001173 if (StringLiteral.hadError)
1174 goto retry;
1175
1176 // Copy the string literal into our string data allocator.
1177 unsigned Length = StringLiteral.GetStringLength();
1178 char *Saved = StringData.Allocate<char>(Length + 1);
1179 memcpy(Saved, StringLiteral.GetString().data(), Length);
1180 Saved[Length] = 0;
1181
1182 // Form the token.
1183 Tok.Kind = MMToken::StringLiteral;
1184 Tok.StringData = Saved;
1185 Tok.StringLength = Length;
1186 break;
1187 }
1188
1189 case tok::comment:
1190 goto retry;
1191
1192 default:
1193 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1194 HadError = true;
1195 goto retry;
1196 }
1197
1198 return Result;
1199}
1200
1201void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1202 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001203 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001204 do {
1205 switch (Tok.Kind) {
1206 case MMToken::EndOfFile:
1207 return;
1208
1209 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001210 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001211 return;
1212
1213 ++braceDepth;
1214 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001215
1216 case MMToken::LSquare:
1217 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1218 return;
1219
1220 ++squareDepth;
1221 break;
1222
Douglas Gregor718292f2011-11-11 19:10:28 +00001223 case MMToken::RBrace:
1224 if (braceDepth > 0)
1225 --braceDepth;
1226 else if (Tok.is(K))
1227 return;
1228 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001229
1230 case MMToken::RSquare:
1231 if (squareDepth > 0)
1232 --squareDepth;
1233 else if (Tok.is(K))
1234 return;
1235 break;
1236
Douglas Gregor718292f2011-11-11 19:10:28 +00001237 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001238 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001239 return;
1240 break;
1241 }
1242
1243 consumeToken();
1244 } while (true);
1245}
1246
Douglas Gregore7ab3662011-12-07 02:23:45 +00001247/// \brief Parse a module-id.
1248///
1249/// module-id:
1250/// identifier
1251/// identifier '.' module-id
1252///
1253/// \returns true if an error occurred, false otherwise.
1254bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1255 Id.clear();
1256 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001257 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001258 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1259 consumeToken();
1260 } else {
1261 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1262 return true;
1263 }
1264
1265 if (!Tok.is(MMToken::Period))
1266 break;
1267
1268 consumeToken();
1269 } while (true);
1270
1271 return false;
1272}
1273
Douglas Gregora686e1b2012-01-27 19:52:33 +00001274namespace {
1275 /// \brief Enumerates the known attributes.
1276 enum AttributeKind {
1277 /// \brief An unknown attribute.
1278 AT_unknown,
1279 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001280 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001281 /// \brief The 'extern_c' attribute.
1282 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001283 /// \brief The 'exhaustive' attribute.
1284 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001285 };
1286}
1287
Douglas Gregor718292f2011-11-11 19:10:28 +00001288/// \brief Parse a module declaration.
1289///
1290/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001291/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001292/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1293/// { module-member* }
1294///
Douglas Gregor718292f2011-11-11 19:10:28 +00001295/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001296/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001297/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001298/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001299/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001300/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001301///
1302/// submodule-declaration:
1303/// module-declaration
1304/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001305void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001306 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001307 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1308 if (Tok.is(MMToken::ExternKeyword)) {
1309 parseExternModuleDecl();
1310 return;
1311 }
1312
Douglas Gregorf2161a72011-12-06 17:16:41 +00001313 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001314 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001315 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001316 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001317
Douglas Gregorf2161a72011-12-06 17:16:41 +00001318 // Parse 'explicit' keyword, if present.
1319 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001320 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001321 Explicit = true;
1322 }
1323
1324 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001325 if (Tok.is(MMToken::FrameworkKeyword)) {
1326 consumeToken();
1327 Framework = true;
1328 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001329
1330 // Parse 'module' keyword.
1331 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001332 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001333 consumeToken();
1334 HadError = true;
1335 return;
1336 }
1337 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001338
1339 // If we have a wildcard for the module name, this is an inferred submodule.
1340 // Parse it.
1341 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001342 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001343
1344 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001345 ModuleId Id;
1346 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001347 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001348 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001349 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001350
Douglas Gregore7ab3662011-12-07 02:23:45 +00001351 if (ActiveModule) {
1352 if (Id.size() > 1) {
1353 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1354 << SourceRange(Id.front().second, Id.back().second);
1355
1356 HadError = true;
1357 return;
1358 }
1359 } else if (Id.size() == 1 && Explicit) {
1360 // Top-level modules can't be explicit.
1361 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1362 Explicit = false;
1363 ExplicitLoc = SourceLocation();
1364 HadError = true;
1365 }
1366
1367 Module *PreviousActiveModule = ActiveModule;
1368 if (Id.size() > 1) {
1369 // This module map defines a submodule. Go find the module of which it
1370 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001371 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001372 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001373 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1374 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001375 if (I == 0)
1376 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001377 ActiveModule = Next;
1378 continue;
1379 }
1380
1381 if (ActiveModule) {
1382 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001383 << Id[I].first
1384 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001385 } else {
1386 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1387 }
1388 HadError = true;
1389 return;
1390 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001391
1392 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1393 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1394 "submodule defined in same file as 'module *' that allowed its "
1395 "top-level module");
1396 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1397 }
1398 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001399
1400 StringRef ModuleName = Id.back().first;
1401 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001402
Douglas Gregora686e1b2012-01-27 19:52:33 +00001403 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001404 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001405 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001406
Douglas Gregor718292f2011-11-11 19:10:28 +00001407 // Parse the opening brace.
1408 if (!Tok.is(MMToken::LBrace)) {
1409 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1410 << ModuleName;
1411 HadError = true;
1412 return;
1413 }
1414 SourceLocation LBraceLoc = consumeToken();
1415
1416 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001417 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001418 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1419 // Skip the module definition.
1420 skipUntil(MMToken::RBrace);
1421 if (Tok.is(MMToken::RBrace))
1422 consumeToken();
1423 else {
1424 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1425 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1426 HadError = true;
1427 }
1428 return;
1429 }
1430
Douglas Gregor718292f2011-11-11 19:10:28 +00001431 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1432 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001433 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001434
1435 // Skip the module definition.
1436 skipUntil(MMToken::RBrace);
1437 if (Tok.is(MMToken::RBrace))
1438 consumeToken();
1439
1440 HadError = true;
1441 return;
1442 }
1443
1444 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001445 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1446 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001447 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001448 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001449 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001450 if (Attrs.IsExternC)
1451 ActiveModule->IsExternC = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001452 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001453
Douglas Gregor718292f2011-11-11 19:10:28 +00001454 bool Done = false;
1455 do {
1456 switch (Tok.Kind) {
1457 case MMToken::EndOfFile:
1458 case MMToken::RBrace:
1459 Done = true;
1460 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001461
1462 case MMToken::ConfigMacros:
1463 parseConfigMacros();
1464 break;
1465
Douglas Gregorfb912652013-03-20 21:10:35 +00001466 case MMToken::Conflict:
1467 parseConflict();
1468 break;
1469
Douglas Gregor718292f2011-11-11 19:10:28 +00001470 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001471 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001472 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001473 case MMToken::ModuleKeyword:
1474 parseModuleDecl();
1475 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001476
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001477 case MMToken::ExportKeyword:
1478 parseExportDecl();
1479 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001480
1481 case MMToken::UseKeyword:
1482 parseUseDecl();
1483 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001484
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001485 case MMToken::RequiresKeyword:
1486 parseRequiresDecl();
1487 break;
1488
Richard Smith202210b2014-10-24 20:23:01 +00001489 case MMToken::TextualKeyword:
1490 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001491 break;
Richard Smith306d8922014-10-22 23:50:56 +00001492
Douglas Gregor524e33e2011-12-08 19:11:24 +00001493 case MMToken::UmbrellaKeyword: {
1494 SourceLocation UmbrellaLoc = consumeToken();
1495 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001496 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001497 else
1498 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001499 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001500 }
Richard Smith202210b2014-10-24 20:23:01 +00001501
1502 case MMToken::ExcludeKeyword:
1503 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001504 break;
Richard Smith202210b2014-10-24 20:23:01 +00001505
1506 case MMToken::PrivateKeyword:
1507 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001508 break;
Richard Smith202210b2014-10-24 20:23:01 +00001509
Douglas Gregor322f6332011-12-08 18:00:48 +00001510 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001511 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001512 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001513
1514 case MMToken::LinkKeyword:
1515 parseLinkDecl();
1516 break;
1517
Douglas Gregor718292f2011-11-11 19:10:28 +00001518 default:
1519 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1520 consumeToken();
1521 break;
1522 }
1523 } while (!Done);
1524
1525 if (Tok.is(MMToken::RBrace))
1526 consumeToken();
1527 else {
1528 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1529 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1530 HadError = true;
1531 }
1532
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001533 // If the active module is a top-level framework, and there are no link
1534 // libraries, automatically link against the framework.
1535 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1536 ActiveModule->LinkLibraries.empty()) {
1537 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1538 }
1539
Ben Langmuirec8c9752014-04-18 22:07:31 +00001540 // If the module meets all requirements but is still unavailable, mark the
1541 // whole tree as unavailable to prevent it from building.
1542 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1543 ActiveModule->Parent) {
1544 ActiveModule->getTopLevelModule()->markUnavailable();
1545 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1546 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1547 }
1548
Douglas Gregore7ab3662011-12-07 02:23:45 +00001549 // We're done parsing this module. Pop back to the previous module.
1550 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001551}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001552
Daniel Jasper97292842013-09-11 07:20:44 +00001553/// \brief Parse an extern module declaration.
1554///
1555/// extern module-declaration:
1556/// 'extern' 'module' module-id string-literal
1557void ModuleMapParser::parseExternModuleDecl() {
1558 assert(Tok.is(MMToken::ExternKeyword));
1559 consumeToken(); // 'extern' keyword
1560
1561 // Parse 'module' keyword.
1562 if (!Tok.is(MMToken::ModuleKeyword)) {
1563 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1564 consumeToken();
1565 HadError = true;
1566 return;
1567 }
1568 consumeToken(); // 'module' keyword
1569
1570 // Parse the module name.
1571 ModuleId Id;
1572 if (parseModuleId(Id)) {
1573 HadError = true;
1574 return;
1575 }
1576
1577 // Parse the referenced module map file name.
1578 if (!Tok.is(MMToken::StringLiteral)) {
1579 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1580 HadError = true;
1581 return;
1582 }
1583 std::string FileName = Tok.getString();
1584 consumeToken(); // filename
1585
1586 StringRef FileNameRef = FileName;
1587 SmallString<128> ModuleMapFileName;
1588 if (llvm::sys::path::is_relative(FileNameRef)) {
1589 ModuleMapFileName += Directory->getName();
1590 llvm::sys::path::append(ModuleMapFileName, FileName);
1591 FileNameRef = ModuleMapFileName.str();
1592 }
1593 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Duncan P. N. Exon Smith00a4da72014-12-09 06:35:37 +00001594 Map.parseModuleMapFile(File, /*IsSystem=*/false);
Daniel Jasper97292842013-09-11 07:20:44 +00001595}
1596
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001597/// \brief Parse a requires declaration.
1598///
1599/// requires-declaration:
1600/// 'requires' feature-list
1601///
1602/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001603/// feature ',' feature-list
1604/// feature
1605///
1606/// feature:
1607/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001608void ModuleMapParser::parseRequiresDecl() {
1609 assert(Tok.is(MMToken::RequiresKeyword));
1610
1611 // Parse 'requires' keyword.
1612 consumeToken();
1613
1614 // Parse the feature-list.
1615 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001616 bool RequiredState = true;
1617 if (Tok.is(MMToken::Exclaim)) {
1618 RequiredState = false;
1619 consumeToken();
1620 }
1621
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001622 if (!Tok.is(MMToken::Identifier)) {
1623 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1624 HadError = true;
1625 return;
1626 }
1627
1628 // Consume the feature name.
1629 std::string Feature = Tok.getString();
1630 consumeToken();
1631
1632 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001633 ActiveModule->addRequirement(Feature, RequiredState,
1634 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001635
1636 if (!Tok.is(MMToken::Comma))
1637 break;
1638
1639 // Consume the comma.
1640 consumeToken();
1641 } while (true);
1642}
1643
Douglas Gregorf2161a72011-12-06 17:16:41 +00001644/// \brief Append to \p Paths the set of paths needed to get to the
1645/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001646static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001647 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001648 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001649 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001650 for (; Mod; Mod = Mod->Parent) {
1651 if (Mod->IsFramework)
1652 Paths.push_back(Mod->Name);
1653 }
1654
1655 if (Paths.empty())
1656 return;
1657
1658 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001659 for (unsigned I = Paths.size() - 1; I != 0; --I)
1660 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001661}
1662
Douglas Gregor718292f2011-11-11 19:10:28 +00001663/// \brief Parse a header declaration.
1664///
1665/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001666/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001667/// 'private' 'textual'[opt] 'header' string-literal
1668/// 'exclude' 'header' string-literal
1669/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001670///
1671/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001672void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1673 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001674 // We've already consumed the first token.
1675 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1676 if (LeadingToken == MMToken::PrivateKeyword) {
1677 Role = ModuleMap::PrivateHeader;
1678 // 'private' may optionally be followed by 'textual'.
1679 if (Tok.is(MMToken::TextualKeyword)) {
1680 LeadingToken = Tok.Kind;
1681 consumeToken();
1682 }
1683 }
1684 if (LeadingToken == MMToken::TextualKeyword)
1685 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1686
1687 if (LeadingToken != MMToken::HeaderKeyword) {
1688 if (!Tok.is(MMToken::HeaderKeyword)) {
1689 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1690 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1691 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1692 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1693 return;
1694 }
1695 consumeToken();
1696 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001697
Douglas Gregor718292f2011-11-11 19:10:28 +00001698 // Parse the header name.
1699 if (!Tok.is(MMToken::StringLiteral)) {
1700 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1701 << "header";
1702 HadError = true;
1703 return;
1704 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001705 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001706 Header.FileName = Tok.getString();
1707 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001708
Douglas Gregor524e33e2011-12-08 19:11:24 +00001709 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001710 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001711 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001712 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001713 HadError = true;
1714 return;
1715 }
1716
Douglas Gregor5257fc62011-11-11 21:55:48 +00001717 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001718 const FileEntry *File = nullptr;
1719 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001720 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001721 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001722 RelativePathName = Header.FileName;
1723 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001724 } else {
1725 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001726 SmallString<128> FullPathName(Directory->getName());
1727 unsigned FullPathLength = FullPathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001728
Douglas Gregorf2161a72011-12-06 17:16:41 +00001729 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001730 appendSubframeworkPaths(ActiveModule, RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001731
1732 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001733 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
1734 llvm::sys::path::append(FullPathName, RelativePathName.str());
1735 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001736
1737 if (!File) {
1738 // Check whether this file is in the private headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001739 // FIXME: Should we retain the subframework paths here?
1740 RelativePathName.clear();
1741 FullPathName.resize(FullPathLength);
1742 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1743 Header.FileName);
1744 llvm::sys::path::append(FullPathName, RelativePathName.str());
1745 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001746 }
1747 } else {
1748 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001749 llvm::sys::path::append(RelativePathName, Header.FileName);
1750 llvm::sys::path::append(FullPathName, RelativePathName.str());
1751 File = SourceMgr.getFileManager().getFile(FullPathName);
1752
Douglas Gregor3ec66632012-02-02 18:42:48 +00001753 // If this is a system module with a top-level header, this header
1754 // may have a counterpart (or replacement) in the set of headers
1755 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001756 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1757 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001758 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001759 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001760 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001761 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001762
Douglas Gregor3ec66632012-02-02 18:42:48 +00001763 // If Clang supplies this header but the underlying system does not,
1764 // just silently swap in our builtin version. Otherwise, we'll end
1765 // up adding both (later).
1766 if (!File && BuiltinFile) {
1767 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001768 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001769 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001770 }
1771 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001772 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001773 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001774
Douglas Gregor5257fc62011-11-11 21:55:48 +00001775 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1776 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001777 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001778 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001779 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001780 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001781 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001782 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001783 HadError = true;
1784 } else {
1785 // Record this umbrella header.
1786 Map.setUmbrellaHeader(ActiveModule, File);
1787 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001788 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001789 Module::Header H = {RelativePathName.str(), File};
1790 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001791 } else {
Richard Smith25d50752014-10-20 00:15:49 +00001792 // If there is a builtin counterpart to this file, add it now, before
1793 // the "real" header, so we build the built-in one first when building
1794 // the module.
Hans Wennborg0101b542014-12-02 02:13:09 +00001795 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001796 // FIXME: Taking the name from the FileEntry is unstable and can give
1797 // different results depending on how we've previously named that file
1798 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001799 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1800 Map.addHeader(ActiveModule, H, Role);
1801 }
Richard Smith25d50752014-10-20 00:15:49 +00001802
Richard Smith202210b2014-10-24 20:23:01 +00001803 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001804 Module::Header H = { RelativePathName.str(), File };
1805 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001806 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001807 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001808 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001809
1810 // If we find a module that has a missing header, we mark this module as
1811 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001812 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001813 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001814 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001815 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001816}
1817
Douglas Gregor524e33e2011-12-08 19:11:24 +00001818/// \brief Parse an umbrella directory declaration.
1819///
1820/// umbrella-dir-declaration:
1821/// umbrella string-literal
1822void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1823 // Parse the directory name.
1824 if (!Tok.is(MMToken::StringLiteral)) {
1825 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1826 << "umbrella";
1827 HadError = true;
1828 return;
1829 }
1830
1831 std::string DirName = Tok.getString();
1832 SourceLocation DirNameLoc = consumeToken();
1833
1834 // Check whether we already have an umbrella.
1835 if (ActiveModule->Umbrella) {
1836 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1837 << ActiveModule->getFullModuleName();
1838 HadError = true;
1839 return;
1840 }
1841
1842 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001843 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001844 if (llvm::sys::path::is_absolute(DirName))
1845 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1846 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001847 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001848 PathName = Directory->getName();
1849 llvm::sys::path::append(PathName, DirName);
1850 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1851 }
1852
1853 if (!Dir) {
1854 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1855 << DirName;
1856 HadError = true;
1857 return;
1858 }
1859
1860 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1861 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1862 << OwningModule->getFullModuleName();
1863 HadError = true;
1864 return;
1865 }
1866
1867 // Record this umbrella directory.
1868 Map.setUmbrellaDir(ActiveModule, Dir);
1869}
1870
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001871/// \brief Parse a module export declaration.
1872///
1873/// export-declaration:
1874/// 'export' wildcard-module-id
1875///
1876/// wildcard-module-id:
1877/// identifier
1878/// '*'
1879/// identifier '.' wildcard-module-id
1880void ModuleMapParser::parseExportDecl() {
1881 assert(Tok.is(MMToken::ExportKeyword));
1882 SourceLocation ExportLoc = consumeToken();
1883
1884 // Parse the module-id with an optional wildcard at the end.
1885 ModuleId ParsedModuleId;
1886 bool Wildcard = false;
1887 do {
Richard Smith306d8922014-10-22 23:50:56 +00001888 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001889 if (Tok.is(MMToken::Identifier)) {
1890 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1891 Tok.getLocation()));
1892 consumeToken();
1893
1894 if (Tok.is(MMToken::Period)) {
1895 consumeToken();
1896 continue;
1897 }
1898
1899 break;
1900 }
1901
1902 if(Tok.is(MMToken::Star)) {
1903 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001904 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001905 break;
1906 }
1907
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001908 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001909 HadError = true;
1910 return;
1911 } while (true);
1912
1913 Module::UnresolvedExportDecl Unresolved = {
1914 ExportLoc, ParsedModuleId, Wildcard
1915 };
1916 ActiveModule->UnresolvedExports.push_back(Unresolved);
1917}
1918
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001919/// \brief Parse a module uses declaration.
1920///
1921/// uses-declaration:
1922/// 'uses' wildcard-module-id
1923void ModuleMapParser::parseUseDecl() {
1924 assert(Tok.is(MMToken::UseKeyword));
1925 consumeToken();
1926 // Parse the module-id.
1927 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001928 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001929
1930 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1931}
1932
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001933/// \brief Parse a link declaration.
1934///
1935/// module-declaration:
1936/// 'link' 'framework'[opt] string-literal
1937void ModuleMapParser::parseLinkDecl() {
1938 assert(Tok.is(MMToken::LinkKeyword));
1939 SourceLocation LinkLoc = consumeToken();
1940
1941 // Parse the optional 'framework' keyword.
1942 bool IsFramework = false;
1943 if (Tok.is(MMToken::FrameworkKeyword)) {
1944 consumeToken();
1945 IsFramework = true;
1946 }
1947
1948 // Parse the library name
1949 if (!Tok.is(MMToken::StringLiteral)) {
1950 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1951 << IsFramework << SourceRange(LinkLoc);
1952 HadError = true;
1953 return;
1954 }
1955
1956 std::string LibraryName = Tok.getString();
1957 consumeToken();
1958 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1959 IsFramework));
1960}
1961
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001962/// \brief Parse a configuration macro declaration.
1963///
1964/// module-declaration:
1965/// 'config_macros' attributes[opt] config-macro-list?
1966///
1967/// config-macro-list:
1968/// identifier (',' identifier)?
1969void ModuleMapParser::parseConfigMacros() {
1970 assert(Tok.is(MMToken::ConfigMacros));
1971 SourceLocation ConfigMacrosLoc = consumeToken();
1972
1973 // Only top-level modules can have configuration macros.
1974 if (ActiveModule->Parent) {
1975 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1976 }
1977
1978 // Parse the optional attributes.
1979 Attributes Attrs;
1980 parseOptionalAttributes(Attrs);
1981 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1982 ActiveModule->ConfigMacrosExhaustive = true;
1983 }
1984
1985 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00001986 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001987 if (!Tok.is(MMToken::Identifier))
1988 return;
1989
1990 // Consume the first identifier.
1991 if (!ActiveModule->Parent) {
1992 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1993 }
1994 consumeToken();
1995
1996 do {
1997 // If there's a comma, consume it.
1998 if (!Tok.is(MMToken::Comma))
1999 break;
2000 consumeToken();
2001
2002 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002003 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002004 if (!Tok.is(MMToken::Identifier)) {
2005 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2006 break;
2007 }
2008
2009 // Consume the macro name.
2010 if (!ActiveModule->Parent) {
2011 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2012 }
2013 consumeToken();
2014 } while (true);
2015}
2016
Douglas Gregorfb912652013-03-20 21:10:35 +00002017/// \brief Format a module-id into a string.
2018static std::string formatModuleId(const ModuleId &Id) {
2019 std::string result;
2020 {
2021 llvm::raw_string_ostream OS(result);
2022
2023 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2024 if (I)
2025 OS << ".";
2026 OS << Id[I].first;
2027 }
2028 }
2029
2030 return result;
2031}
2032
2033/// \brief Parse a conflict declaration.
2034///
2035/// module-declaration:
2036/// 'conflict' module-id ',' string-literal
2037void ModuleMapParser::parseConflict() {
2038 assert(Tok.is(MMToken::Conflict));
2039 SourceLocation ConflictLoc = consumeToken();
2040 Module::UnresolvedConflict Conflict;
2041
2042 // Parse the module-id.
2043 if (parseModuleId(Conflict.Id))
2044 return;
2045
2046 // Parse the ','.
2047 if (!Tok.is(MMToken::Comma)) {
2048 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2049 << SourceRange(ConflictLoc);
2050 return;
2051 }
2052 consumeToken();
2053
2054 // Parse the message.
2055 if (!Tok.is(MMToken::StringLiteral)) {
2056 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2057 << formatModuleId(Conflict.Id);
2058 return;
2059 }
2060 Conflict.Message = Tok.getString().str();
2061 consumeToken();
2062
2063 // Add this unresolved conflict.
2064 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2065}
2066
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002067/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002068///
2069/// module-declaration:
2070/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2071/// { inferred-module-member* }
2072///
2073/// inferred-module-member:
2074/// 'export' '*'
2075/// 'exclude' identifier
2076void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002077 assert(Tok.is(MMToken::Star));
2078 SourceLocation StarLoc = consumeToken();
2079 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002080
Douglas Gregor73441092011-12-05 22:27:44 +00002081 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002082 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002083 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2084 Failed = true;
2085 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002086
2087 if (ActiveModule) {
2088 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002089 if (!Failed && ActiveModule->IsAvailable &&
2090 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002091 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2092 Failed = true;
2093 }
2094
2095 // Check for redefinition of an inferred module.
2096 if (!Failed && ActiveModule->InferSubmodules) {
2097 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2098 if (ActiveModule->InferredSubmoduleLoc.isValid())
2099 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2100 diag::note_mmap_prev_definition);
2101 Failed = true;
2102 }
2103
2104 // Check for the 'framework' keyword, which is not permitted here.
2105 if (Framework) {
2106 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2107 Framework = false;
2108 }
2109 } else if (Explicit) {
2110 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2111 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002112 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002113
Douglas Gregor73441092011-12-05 22:27:44 +00002114 // If there were any problems with this inferred submodule, skip its body.
2115 if (Failed) {
2116 if (Tok.is(MMToken::LBrace)) {
2117 consumeToken();
2118 skipUntil(MMToken::RBrace);
2119 if (Tok.is(MMToken::RBrace))
2120 consumeToken();
2121 }
2122 HadError = true;
2123 return;
2124 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002125
2126 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002127 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002128 parseOptionalAttributes(Attrs);
2129
2130 if (ActiveModule) {
2131 // Note that we have an inferred submodule.
2132 ActiveModule->InferSubmodules = true;
2133 ActiveModule->InferredSubmoduleLoc = StarLoc;
2134 ActiveModule->InferExplicitSubmodules = Explicit;
2135 } else {
2136 // We'll be inferring framework modules for this directory.
2137 Map.InferredDirectories[Directory].InferModules = true;
2138 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002139 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002140 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002141 }
2142
Douglas Gregor73441092011-12-05 22:27:44 +00002143 // Parse the opening brace.
2144 if (!Tok.is(MMToken::LBrace)) {
2145 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2146 HadError = true;
2147 return;
2148 }
2149 SourceLocation LBraceLoc = consumeToken();
2150
2151 // Parse the body of the inferred submodule.
2152 bool Done = false;
2153 do {
2154 switch (Tok.Kind) {
2155 case MMToken::EndOfFile:
2156 case MMToken::RBrace:
2157 Done = true;
2158 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002159
2160 case MMToken::ExcludeKeyword: {
2161 if (ActiveModule) {
2162 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002163 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002164 consumeToken();
2165 break;
2166 }
2167
2168 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002169 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002170 if (!Tok.is(MMToken::Identifier)) {
2171 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2172 break;
2173 }
2174
2175 Map.InferredDirectories[Directory].ExcludedModules
2176 .push_back(Tok.getString());
2177 consumeToken();
2178 break;
2179 }
2180
2181 case MMToken::ExportKeyword:
2182 if (!ActiveModule) {
2183 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002184 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002185 consumeToken();
2186 break;
2187 }
2188
Douglas Gregor73441092011-12-05 22:27:44 +00002189 consumeToken();
2190 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002191 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002192 else
2193 Diags.Report(Tok.getLocation(),
2194 diag::err_mmap_expected_export_wildcard);
2195 consumeToken();
2196 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002197
Douglas Gregor73441092011-12-05 22:27:44 +00002198 case MMToken::ExplicitKeyword:
2199 case MMToken::ModuleKeyword:
2200 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002201 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002202 case MMToken::UmbrellaKeyword:
2203 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002204 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002205 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002206 consumeToken();
2207 break;
2208 }
2209 } while (!Done);
2210
2211 if (Tok.is(MMToken::RBrace))
2212 consumeToken();
2213 else {
2214 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2215 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2216 HadError = true;
2217 }
2218}
2219
Douglas Gregor9194a912012-11-06 19:39:40 +00002220/// \brief Parse optional attributes.
2221///
2222/// attributes:
2223/// attribute attributes
2224/// attribute
2225///
2226/// attribute:
2227/// [ identifier ]
2228///
2229/// \param Attrs Will be filled in with the parsed attributes.
2230///
2231/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002232bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002233 bool HadError = false;
2234
2235 while (Tok.is(MMToken::LSquare)) {
2236 // Consume the '['.
2237 SourceLocation LSquareLoc = consumeToken();
2238
2239 // Check whether we have an attribute name here.
2240 if (!Tok.is(MMToken::Identifier)) {
2241 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2242 skipUntil(MMToken::RSquare);
2243 if (Tok.is(MMToken::RSquare))
2244 consumeToken();
2245 HadError = true;
2246 }
2247
2248 // Decode the attribute name.
2249 AttributeKind Attribute
2250 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002251 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002252 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002253 .Case("system", AT_system)
2254 .Default(AT_unknown);
2255 switch (Attribute) {
2256 case AT_unknown:
2257 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2258 << Tok.getString();
2259 break;
2260
2261 case AT_system:
2262 Attrs.IsSystem = true;
2263 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002264
Richard Smith77944862014-03-02 05:58:18 +00002265 case AT_extern_c:
2266 Attrs.IsExternC = true;
2267 break;
2268
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002269 case AT_exhaustive:
2270 Attrs.IsExhaustive = true;
2271 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002272 }
2273 consumeToken();
2274
2275 // Consume the ']'.
2276 if (!Tok.is(MMToken::RSquare)) {
2277 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2278 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2279 skipUntil(MMToken::RSquare);
2280 HadError = true;
2281 }
2282
2283 if (Tok.is(MMToken::RSquare))
2284 consumeToken();
2285 }
2286
2287 return HadError;
2288}
2289
Douglas Gregor718292f2011-11-11 19:10:28 +00002290/// \brief Parse a module map file.
2291///
2292/// module-map-file:
2293/// module-declaration*
2294bool ModuleMapParser::parseModuleMapFile() {
2295 do {
2296 switch (Tok.Kind) {
2297 case MMToken::EndOfFile:
2298 return HadError;
2299
Douglas Gregore7ab3662011-12-07 02:23:45 +00002300 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002301 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002302 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002303 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002304 parseModuleDecl();
2305 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002306
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002307 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002308 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002309 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002310 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002311 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002312 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002313 case MMToken::HeaderKeyword:
2314 case MMToken::Identifier:
2315 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002316 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002317 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002318 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002319 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002320 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002321 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002322 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002323 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002324 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002325 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002326 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002327 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002328 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2329 HadError = true;
2330 consumeToken();
2331 break;
2332 }
2333 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002334}
2335
Duncan P. N. Exon Smith00a4da72014-12-09 06:35:37 +00002336bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002337 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2338 = ParsedModuleMap.find(File);
2339 if (Known != ParsedModuleMap.end())
2340 return Known->second;
2341
Craig Topperd2d442c2014-05-17 23:10:59 +00002342 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002343 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2344 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002345 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002346 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002347 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002348
Duncan P. N. Exon Smith00a4da72014-12-09 06:35:37 +00002349 // Find the directory for the module. For frameworks, that may require going
2350 // up from the 'Modules' directory.
2351 const DirectoryEntry *Dir = File->getDir();
2352 StringRef DirName(Dir->getName());
2353 if (llvm::sys::path::filename(DirName) == "Modules") {
2354 DirName = llvm::sys::path::parent_path(DirName);
2355 if (DirName.endswith(".framework"))
2356 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2357 assert(Dir && "parent must exist");
2358 }
2359
Douglas Gregor718292f2011-11-11 19:10:28 +00002360 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002361 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002362 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002363 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002364 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002365 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002366 return Result;
2367}