blob: f4dfa12854a353caf15c1feff952328ad2ff4fb3 [file] [log] [blame]
Douglas Gregora30cfe52011-11-11 19:10:28 +00001//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ModuleMap implementation, which describes the layout
11// of a module as it relates to headers.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/Lex/ModuleMap.h"
Jordan Rose3f6f51e2013-02-08 22:30:41 +000015#include "clang/Basic/CharInfo.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000016#include "clang/Basic/Diagnostic.h"
Douglas Gregor02c23eb2012-10-23 22:26:28 +000017#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000018#include "clang/Basic/FileManager.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Basic/TargetOptions.h"
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000021#include "clang/Lex/HeaderSearch.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000022#include "clang/Lex/LexDiagnostic.h"
23#include "clang/Lex/Lexer.h"
24#include "clang/Lex/LiteralSupport.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/ADT/StringSwitch.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000027#include "llvm/Support/Allocator.h"
Douglas Gregorac252a32011-12-06 19:39:29 +000028#include "llvm/Support/FileSystem.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000029#include "llvm/Support/Host.h"
Rafael Espindola8229d222013-06-11 22:15:02 +000030#include "llvm/Support/Path.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000031#include "llvm/Support/raw_ostream.h"
Douglas Gregor98cfcbf2012-09-27 14:50:15 +000032#include <stdlib.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000033#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoadeb7822013-01-26 16:29:36 +000034#include <limits.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000035#endif
Douglas Gregora30cfe52011-11-11 19:10:28 +000036using namespace clang;
37
Douglas Gregor90db2602011-12-02 01:47:07 +000038Module::ExportDecl
39ModuleMap::resolveExport(Module *Mod,
40 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +000041 bool Complain) const {
Douglas Gregor0adaa882011-12-05 17:28:06 +000042 // We may have just a wildcard.
43 if (Unresolved.Id.empty()) {
44 assert(Unresolved.Wildcard && "Invalid unresolved export");
45 return Module::ExportDecl(0, true);
46 }
47
Douglas Gregor906d66a2013-03-20 21:10:35 +000048 // Resolve the module-id.
49 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
50 if (!Context)
51 return Module::ExportDecl();
52
53 return Module::ExportDecl(Context, Unresolved.Wildcard);
54}
55
56Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
57 bool Complain) const {
Douglas Gregor90db2602011-12-02 01:47:07 +000058 // Find the starting module.
Douglas Gregor906d66a2013-03-20 21:10:35 +000059 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor90db2602011-12-02 01:47:07 +000060 if (!Context) {
61 if (Complain)
Douglas Gregor906d66a2013-03-20 21:10:35 +000062 Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
63 << Id[0].first << Mod->getFullModuleName();
64
65 return 0;
Douglas Gregor90db2602011-12-02 01:47:07 +000066 }
67
68 // Dig into the module path.
Douglas Gregor906d66a2013-03-20 21:10:35 +000069 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
70 Module *Sub = lookupModuleQualified(Id[I].first, Context);
Douglas Gregor90db2602011-12-02 01:47:07 +000071 if (!Sub) {
72 if (Complain)
Douglas Gregor906d66a2013-03-20 21:10:35 +000073 Diags->Report(Id[I].second, diag::err_mmap_missing_module_qualified)
74 << Id[I].first << Context->getFullModuleName()
75 << SourceRange(Id[0].second, Id[I-1].second);
76
77 return 0;
Douglas Gregor90db2602011-12-02 01:47:07 +000078 }
Douglas Gregor906d66a2013-03-20 21:10:35 +000079
Douglas Gregor90db2602011-12-02 01:47:07 +000080 Context = Sub;
81 }
Douglas Gregor906d66a2013-03-20 21:10:35 +000082
83 return Context;
Douglas Gregor90db2602011-12-02 01:47:07 +000084}
85
Manuel Klimekee0cd372013-10-24 07:51:24 +000086ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticConsumer &DC,
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000087 const LangOptions &LangOpts, const TargetInfo *Target,
88 HeaderSearch &HeaderInfo)
Manuel Klimekee0cd372013-10-24 07:51:24 +000089 : SourceMgr(SourceMgr), LangOpts(LangOpts), Target(Target),
90 HeaderInfo(HeaderInfo), BuiltinIncludeDir(0), CompilingModule(0),
91 SourceModule(0) {
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000092 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
93 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000094 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora4a90ca2013-05-03 22:58:43 +000095 Diags->setClient(new ForwardingDiagnosticConsumer(DC),
96 /*ShouldOwnClient=*/true);
Manuel Klimekee0cd372013-10-24 07:51:24 +000097 Diags->setSourceManager(&SourceMgr);
Douglas Gregora30cfe52011-11-11 19:10:28 +000098}
99
100ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +0000101 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
102 IEnd = Modules.end();
103 I != IEnd; ++I) {
104 delete I->getValue();
105 }
Douglas Gregora30cfe52011-11-11 19:10:28 +0000106}
107
Douglas Gregordc58aa72012-01-30 06:01:29 +0000108void ModuleMap::setTarget(const TargetInfo &Target) {
109 assert((!this->Target || this->Target == &Target) &&
110 "Improper target override");
111 this->Target = &Target;
112}
113
Douglas Gregor8b48e082012-10-12 21:15:50 +0000114/// \brief "Sanitize" a filename so that it can be used as an identifier.
115static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
116 SmallVectorImpl<char> &Buffer) {
117 if (Name.empty())
118 return Name;
119
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000120 if (!isValidIdentifier(Name)) {
Douglas Gregor8b48e082012-10-12 21:15:50 +0000121 // If we don't already have something with the form of an identifier,
122 // create a buffer with the sanitized name.
123 Buffer.clear();
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000124 if (isDigit(Name[0]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000125 Buffer.push_back('_');
126 Buffer.reserve(Buffer.size() + Name.size());
127 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000128 if (isIdentifierBody(Name[I]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000129 Buffer.push_back(Name[I]);
130 else
131 Buffer.push_back('_');
132 }
133
134 Name = StringRef(Buffer.data(), Buffer.size());
135 }
136
137 while (llvm::StringSwitch<bool>(Name)
138#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
139#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
140#include "clang/Basic/TokenKinds.def"
141 .Default(false)) {
142 if (Name.data() != Buffer.data())
143 Buffer.append(Name.begin(), Name.end());
144 Buffer.push_back('_');
145 Name = StringRef(Buffer.data(), Buffer.size());
146 }
147
148 return Name;
149}
150
Douglas Gregordb3910b2013-05-02 17:58:30 +0000151/// \brief Determine whether the given file name is the name of a builtin
152/// header, supplied by Clang to replace, override, or augment existing system
153/// headers.
154static bool isBuiltinHeader(StringRef FileName) {
155 return llvm::StringSwitch<bool>(FileName)
156 .Case("float.h", true)
157 .Case("iso646.h", true)
158 .Case("limits.h", true)
159 .Case("stdalign.h", true)
160 .Case("stdarg.h", true)
161 .Case("stdbool.h", true)
162 .Case("stddef.h", true)
163 .Case("stdint.h", true)
164 .Case("tgmath.h", true)
165 .Case("unwind.h", true)
166 .Default(false);
167}
168
Daniel Jasperc6417092013-10-22 08:09:47 +0000169ModuleMap::KnownHeader
170ModuleMap::findModuleForHeader(const FileEntry *File,
171 Module *RequestingModule) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000172 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000173 if (Known != Headers.end()) {
Daniel Jasperc6417092013-10-22 08:09:47 +0000174 ModuleMap::KnownHeader Result = KnownHeader();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000175
Daniel Jasperc6417092013-10-22 08:09:47 +0000176 // Iterate over all modules that 'File' is part of to find the best fit.
177 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
178 E = Known->second.end();
179 I != E; ++I) {
180 // Cannot use a module if the header is excluded or unavailable in it.
181 if (I->getRole() == ModuleMap::ExcludedHeader ||
182 !I->getModule()->isAvailable())
183 continue;
184
185 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
186 // module we are looking for.
187 if (I->getModule() == RequestingModule)
188 return *I;
189
190 // If uses need to be specified explicitly, we are only allowed to return
191 // modules that are explicitly used by the requesting module.
192 if (RequestingModule && LangOpts.ModulesDeclUse &&
193 std::find(RequestingModule->DirectUses.begin(),
194 RequestingModule->DirectUses.end(),
195 I->getModule()) == RequestingModule->DirectUses.end())
196 continue;
197 Result = *I;
198 // If 'File' is a public header of this module, this is as good as we
199 // are going to get.
200 if (I->getRole() == ModuleMap::NormalHeader)
201 break;
202 }
203 return Result;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000204 }
Douglas Gregordb3910b2013-05-02 17:58:30 +0000205
206 // If we've found a builtin header within Clang's builtin include directory,
207 // load all of the module maps to see if it will get associated with a
208 // specific module (e.g., in /usr/include).
209 if (File->getDir() == BuiltinIncludeDir &&
210 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
Douglas Gregor30a16f12013-05-10 22:52:27 +0000211 HeaderInfo.loadTopLevelSystemModules();
Douglas Gregordb3910b2013-05-02 17:58:30 +0000212
213 // Check again.
Daniel Jasperc6417092013-10-22 08:09:47 +0000214 if (Headers.find(File) != Headers.end())
215 return findModuleForHeader(File, RequestingModule);
Douglas Gregordb3910b2013-05-02 17:58:30 +0000216 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000217
Douglas Gregoradb97992011-11-16 23:02:25 +0000218 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000219 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000220
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000221 // Note: as an egregious but useful hack we use the real path here, because
222 // frameworks moving from top-level frameworks to embedded frameworks tend
223 // to be symlinked from the top-level location to the embedded location,
224 // and we need to resolve lookups as if we had found the embedded location.
Manuel Klimekee0cd372013-10-24 07:51:24 +0000225 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000226
227 // Keep walking up the directory hierarchy, looking for a directory with
228 // an umbrella header.
229 do {
230 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
231 = UmbrellaDirs.find(Dir);
232 if (KnownDir != UmbrellaDirs.end()) {
233 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000234
235 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000236 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000237 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000238 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000239 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000240
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000241 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000242 // Infer submodules for each of the directories we found between
243 // the directory of the umbrella header and the directory where
244 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000245 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000246
Douglas Gregor6a1db482011-12-09 02:04:43 +0000247 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000248 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000249 SmallString<32> NameBuf;
250 StringRef Name = sanitizeFilenameAsIdentifier(
251 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
252 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000253 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000254 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000255
256 // Associate the module and the directory.
257 UmbrellaDirs[SkippedDirs[I-1]] = Result;
258
259 // If inferred submodules export everything they import, add a
260 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000261 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000262 Result->Exports.push_back(Module::ExportDecl(0, true));
263 }
264
265 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000266 SmallString<32> NameBuf;
267 StringRef Name = sanitizeFilenameAsIdentifier(
268 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000269 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000270 Explicit).first;
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +0000271 Result->addTopHeader(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000272
273 // If inferred submodules export everything they import, add a
274 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000275 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000276 Result->Exports.push_back(Module::ExportDecl(0, true));
277 } else {
278 // Record each of the directories we stepped through as being part of
279 // the module we found, since the umbrella header covers them all.
280 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
281 UmbrellaDirs[SkippedDirs[I]] = Result;
282 }
283
Daniel Jasperc6417092013-10-22 08:09:47 +0000284 Headers[File].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor51f564f2011-12-31 04:05:44 +0000285
286 // If a header corresponds to an unavailable module, don't report
287 // that it maps to anything.
288 if (!Result->isAvailable())
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000289 return KnownHeader();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000290
Daniel Jasperc6417092013-10-22 08:09:47 +0000291 return Headers[File].back();
Douglas Gregore209e502011-12-06 01:10:29 +0000292 }
293
294 SkippedDirs.push_back(Dir);
295
Douglas Gregoradb97992011-11-16 23:02:25 +0000296 // Retrieve our parent path.
297 DirName = llvm::sys::path::parent_path(DirName);
298 if (DirName.empty())
299 break;
300
301 // Resolve the parent path to a directory entry.
Manuel Klimekee0cd372013-10-24 07:51:24 +0000302 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000303 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000304
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000305 return KnownHeader();
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000306}
307
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000308bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
309 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasperc6417092013-10-22 08:09:47 +0000310 if (Known != Headers.end()) {
311 for (SmallVectorImpl<KnownHeader>::const_iterator
312 I = Known->second.begin(),
313 E = Known->second.end();
314 I != E; ++I) {
315 if (I->isAvailable())
316 return false;
317 }
318 return true;
319 }
Douglas Gregor51f564f2011-12-31 04:05:44 +0000320
321 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000322 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000323 StringRef DirName = Dir->getName();
324
325 // Keep walking up the directory hierarchy, looking for a directory with
326 // an umbrella header.
327 do {
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000328 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor51f564f2011-12-31 04:05:44 +0000329 = UmbrellaDirs.find(Dir);
330 if (KnownDir != UmbrellaDirs.end()) {
331 Module *Found = KnownDir->second;
332 if (!Found->isAvailable())
333 return true;
334
335 // Search up the module stack until we find a module with an umbrella
336 // directory.
337 Module *UmbrellaModule = Found;
338 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
339 UmbrellaModule = UmbrellaModule->Parent;
340
341 if (UmbrellaModule->InferSubmodules) {
342 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
343 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000344 SmallString<32> NameBuf;
345 StringRef Name = sanitizeFilenameAsIdentifier(
346 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
347 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000348 Found = lookupModuleQualified(Name, Found);
349 if (!Found)
350 return false;
351 if (!Found->isAvailable())
352 return true;
353 }
354
355 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000356 SmallString<32> NameBuf;
357 StringRef Name = sanitizeFilenameAsIdentifier(
358 llvm::sys::path::stem(Header->getName()),
359 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000360 Found = lookupModuleQualified(Name, Found);
361 if (!Found)
362 return false;
363 }
364
365 return !Found->isAvailable();
366 }
367
368 SkippedDirs.push_back(Dir);
369
370 // Retrieve our parent path.
371 DirName = llvm::sys::path::parent_path(DirName);
372 if (DirName.empty())
373 break;
374
375 // Resolve the parent path to a directory entry.
Manuel Klimekee0cd372013-10-24 07:51:24 +0000376 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000377 } while (Dir);
378
379 return false;
380}
381
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000382Module *ModuleMap::findModule(StringRef Name) const {
383 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor484535e2011-11-11 23:20:24 +0000384 if (Known != Modules.end())
385 return Known->getValue();
386
387 return 0;
388}
389
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000390Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
391 Module *Context) const {
Douglas Gregor90db2602011-12-02 01:47:07 +0000392 for(; Context; Context = Context->Parent) {
393 if (Module *Sub = lookupModuleQualified(Name, Context))
394 return Sub;
395 }
396
397 return findModule(Name);
398}
399
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000400Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor90db2602011-12-02 01:47:07 +0000401 if (!Context)
402 return findModule(Name);
403
Douglas Gregorb7a78192012-01-04 23:32:19 +0000404 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000405}
406
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000407std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000408ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
409 bool IsExplicit) {
410 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000411 if (Module *Sub = lookupModuleQualified(Name, Parent))
412 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000413
414 // Create a new module with this name.
415 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
416 IsExplicit);
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000417 if (LangOpts.CurrentModule == Name) {
418 SourceModule = Result;
419 SourceModuleName = Name;
420 }
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000421 if (!Parent) {
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000422 Modules[Name] = Result;
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000423 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
424 Name == LangOpts.CurrentModule) {
425 CompilingModule = Result;
426 }
427 }
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000428 return std::make_pair(Result, true);
429}
430
Douglas Gregor82e52372012-11-06 19:39:40 +0000431bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000432 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000433 // Check whether we have already looked into the parent directory
434 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000435 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000436 inferred = InferredDirectories.find(ParentDir);
437 if (inferred == InferredDirectories.end())
438 return false;
439
440 if (!inferred->second.InferModules)
441 return false;
442
443 // We're allowed to infer for this directory, but make sure it's okay
444 // to infer this particular module.
445 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
446 inferred->second.ExcludedModules.end(),
447 Name) == inferred->second.ExcludedModules.end();
448
449 if (canInfer && inferred->second.InferSystemModules)
450 IsSystem = true;
451
452 return canInfer;
453}
454
Douglas Gregor8767dc22013-01-14 17:57:51 +0000455/// \brief For a framework module, infer the framework against which we
456/// should link.
457static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
458 FileManager &FileMgr) {
459 assert(Mod->IsFramework && "Can only infer linking for framework modules");
460 assert(!Mod->isSubFramework() &&
461 "Can only infer linking for top-level frameworks");
462
463 SmallString<128> LibName;
464 LibName += FrameworkDir->getName();
465 llvm::sys::path::append(LibName, Mod->Name);
466 if (FileMgr.getFile(LibName)) {
467 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
468 /*IsFramework=*/true));
469 }
470}
471
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000472Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000473ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000474 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000475 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000476 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000477 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000478 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
479 return Mod;
480
Manuel Klimekee0cd372013-10-24 07:51:24 +0000481 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000482
483 // If the framework has a parent path from which we're allowed to infer
484 // a framework module, do so.
485 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000486 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000487
Douglas Gregor7005b902013-01-10 01:43:00 +0000488 // Note: as an egregious but useful hack we use the real path here, because
489 // we might be looking at an embedded framework that symlinks out to a
490 // top-level framework, and we need to infer as if we were naming the
491 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000492 StringRef FrameworkDirName
Manuel Klimekee0cd372013-10-24 07:51:24 +0000493 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000494
Douglas Gregor82e52372012-11-06 19:39:40 +0000495 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000496 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000497 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000498 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000499 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
500 // Check whether we have already looked into the parent directory
501 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000502 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000503 inferred = InferredDirectories.find(ParentDir);
504 if (inferred == InferredDirectories.end()) {
505 // We haven't looked here before. Load a module map, if there is
506 // one.
507 SmallString<128> ModMapPath = Parent;
508 llvm::sys::path::append(ModMapPath, "module.map");
509 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000510 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor82e52372012-11-06 19:39:40 +0000511 inferred = InferredDirectories.find(ParentDir);
512 }
513
514 if (inferred == InferredDirectories.end())
515 inferred = InferredDirectories.insert(
516 std::make_pair(ParentDir, InferredDirectory())).first;
517 }
518
519 if (inferred->second.InferModules) {
520 // We're allowed to infer for this directory, but make sure it's okay
521 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000522 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000523 canInfer = std::find(inferred->second.ExcludedModules.begin(),
524 inferred->second.ExcludedModules.end(),
525 Name) == inferred->second.ExcludedModules.end();
526
527 if (inferred->second.InferSystemModules)
528 IsSystem = true;
529 }
530 }
531 }
532
533 // If we're not allowed to infer a framework module, don't.
534 if (!canInfer)
535 return 0;
536 }
537
538
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000539 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000540 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramerceb6dc82013-06-28 16:25:46 +0000541 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000542 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000543
544 // FIXME: If there's no umbrella header, we could probably scan the
545 // framework to load *everything*. But, it's not clear that this is a good
546 // idea.
547 if (!UmbrellaHeader)
548 return 0;
549
Douglas Gregorac252a32011-12-06 19:39:29 +0000550 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
551 /*IsFramework=*/true, /*IsExplicit=*/false);
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000552 if (LangOpts.CurrentModule == ModuleName) {
553 SourceModule = Result;
554 SourceModuleName = ModuleName;
555 }
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000556 if (IsSystem)
557 Result->IsSystem = IsSystem;
558
Douglas Gregorb7a78192012-01-04 23:32:19 +0000559 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000560 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000561
Douglas Gregor489ad432011-12-08 18:00:48 +0000562 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000563 Result->Umbrella = UmbrellaHeader;
Daniel Jasperc6417092013-10-22 08:09:47 +0000564 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000565 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000566
567 // export *
568 Result->Exports.push_back(Module::ExportDecl(0, true));
569
Douglas Gregore209e502011-12-06 01:10:29 +0000570 // module * { export * }
571 Result->InferSubmodules = true;
572 Result->InferExportWildcard = true;
573
Douglas Gregorac252a32011-12-06 19:39:29 +0000574 // Look for subframeworks.
575 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000576 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000577 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000578 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer0f599ac2013-09-11 11:23:15 +0000579 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000580 for (llvm::sys::fs::directory_iterator
Benjamin Kramer0f599ac2013-09-11 11:23:15 +0000581 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000582 Dir != DirEnd && !EC; Dir.increment(EC)) {
583 if (!StringRef(Dir->path()).endswith(".framework"))
584 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000585
Douglas Gregorac252a32011-12-06 19:39:29 +0000586 if (const DirectoryEntry *SubframeworkDir
587 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000588 // Note: as an egregious but useful hack, we use the real path here and
589 // check whether it is actually a subdirectory of the parent directory.
590 // This will not be the case if the 'subframework' is actually a symlink
591 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000592 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
593 bool FoundParent = false;
594 do {
595 // Get the parent directory name.
596 SubframeworkDirName
597 = llvm::sys::path::parent_path(SubframeworkDirName);
598 if (SubframeworkDirName.empty())
599 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000600
Douglas Gregor713b7c02013-01-26 00:55:12 +0000601 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
602 FoundParent = true;
603 break;
604 }
605 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000606
Douglas Gregor713b7c02013-01-26 00:55:12 +0000607 if (!FoundParent)
608 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000609
Douglas Gregorac252a32011-12-06 19:39:29 +0000610 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000611 SmallString<32> NameBuf;
612 inferFrameworkModule(sanitizeFilenameAsIdentifier(
613 llvm::sys::path::stem(Dir->path()), NameBuf),
614 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000615 }
616 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000617
Douglas Gregor8767dc22013-01-14 17:57:51 +0000618 // If the module is a top-level framework, automatically link against the
619 // framework.
620 if (!Result->isSubFramework()) {
621 inferFrameworkLink(Result, FrameworkDir, FileMgr);
622 }
623
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000624 return Result;
625}
626
Douglas Gregore209e502011-12-06 01:10:29 +0000627void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasperc6417092013-10-22 08:09:47 +0000628 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor10694ce2011-12-08 17:39:04 +0000629 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000630 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000631}
632
Douglas Gregor77d029f2011-12-08 19:11:24 +0000633void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
634 Mod->Umbrella = UmbrellaDir;
635 UmbrellaDirs[UmbrellaDir] = Mod;
636}
637
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000638void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000639 ModuleHeaderRole Role) {
640 if (Role == ExcludedHeader) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000641 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000642 } else {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000643 if (Role == PrivateHeader)
644 Mod->PrivateHeaders.push_back(Header);
645 else
646 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000647 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000648 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000649 }
Daniel Jasperc6417092013-10-22 08:09:47 +0000650 Headers[Header].push_back(KnownHeader(Mod, Role));
Douglas Gregore209e502011-12-06 01:10:29 +0000651}
652
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000653const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000654ModuleMap::getContainingModuleMapFile(Module *Module) const {
Manuel Klimekee0cd372013-10-24 07:51:24 +0000655 if (Module->DefinitionLoc.isInvalid())
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000656 return 0;
657
Manuel Klimekee0cd372013-10-24 07:51:24 +0000658 return SourceMgr.getFileEntryForID(
659 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000660}
661
Douglas Gregora30cfe52011-11-11 19:10:28 +0000662void ModuleMap::dump() {
663 llvm::errs() << "Modules:";
664 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
665 MEnd = Modules.end();
666 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000667 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000668
669 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000670 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000671 H != HEnd; ++H) {
Daniel Jasperc6417092013-10-22 08:09:47 +0000672 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
673 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
674 E = H->second.end();
675 I != E; ++I) {
676 if (I != H->second.begin())
677 llvm::errs() << ",";
678 llvm::errs() << I->getModule()->getFullModuleName();
679 }
680 llvm::errs() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000681 }
682}
683
Douglas Gregor90db2602011-12-02 01:47:07 +0000684bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
685 bool HadError = false;
686 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
687 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
688 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000689 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000690 Mod->Exports.push_back(Export);
691 else
692 HadError = true;
693 }
694 Mod->UnresolvedExports.clear();
695 return HadError;
696}
697
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000698bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
699 bool HadError = false;
700 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
701 Module *DirectUse =
702 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
703 if (DirectUse)
704 Mod->DirectUses.push_back(DirectUse);
705 else
706 HadError = true;
707 }
708 Mod->UnresolvedDirectUses.clear();
709 return HadError;
710}
711
Douglas Gregor906d66a2013-03-20 21:10:35 +0000712bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
713 bool HadError = false;
714 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
715 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
716 Mod, Complain);
717 if (!OtherMod) {
718 HadError = true;
719 continue;
720 }
721
722 Module::Conflict Conflict;
723 Conflict.Other = OtherMod;
724 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
725 Mod->Conflicts.push_back(Conflict);
726 }
727 Mod->UnresolvedConflicts.clear();
728 return HadError;
729}
730
Douglas Gregor55988682011-12-05 16:33:54 +0000731Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
732 if (Loc.isInvalid())
733 return 0;
734
735 // Use the expansion location to determine which module we're in.
736 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
737 if (!ExpansionLoc.isFileID())
738 return 0;
739
740
741 const SourceManager &SrcMgr = Loc.getManager();
742 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000743
Douglas Gregor303aae92012-01-06 17:19:32 +0000744 while (const FileEntry *ExpansionFile
745 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
746 // Find the module that owns this header (if any).
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000747 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor303aae92012-01-06 17:19:32 +0000748 return Mod;
749
750 // No module owns this header, so look up the inclusion chain to see if
751 // any included header has an associated module.
752 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
753 if (IncludeLoc.isInvalid())
754 return 0;
755
756 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
757 }
758
759 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000760}
761
Douglas Gregora30cfe52011-11-11 19:10:28 +0000762//----------------------------------------------------------------------------//
763// Module map file parser
764//----------------------------------------------------------------------------//
765
766namespace clang {
767 /// \brief A token in a module map file.
768 struct MMToken {
769 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000770 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000771 ConfigMacros,
Douglas Gregor906d66a2013-03-20 21:10:35 +0000772 Conflict,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000773 EndOfFile,
774 HeaderKeyword,
775 Identifier,
Richard Smith5794b532013-10-28 22:18:19 +0000776 Exclaim,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000777 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000778 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000779 ExportKeyword,
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000780 ExternKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000781 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000782 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000783 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000784 Period,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000785 PrivateKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000786 UmbrellaKeyword,
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000787 UseKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000788 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000789 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000790 StringLiteral,
791 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000792 RBrace,
793 LSquare,
794 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000795 } Kind;
796
797 unsigned Location;
798 unsigned StringLength;
799 const char *StringData;
800
801 void clear() {
802 Kind = EndOfFile;
803 Location = 0;
804 StringLength = 0;
805 StringData = 0;
806 }
807
808 bool is(TokenKind K) const { return Kind == K; }
809
810 SourceLocation getLocation() const {
811 return SourceLocation::getFromRawEncoding(Location);
812 }
813
814 StringRef getString() const {
815 return StringRef(StringData, StringLength);
816 }
817 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000818
819 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000820 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000821 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000822
823 /// \brief Whether this is a system module.
824 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000825
826 /// \brief Whether this is an exhaustive set of configuration macros.
827 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000828 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000829
Douglas Gregor82e52372012-11-06 19:39:40 +0000830
Douglas Gregora30cfe52011-11-11 19:10:28 +0000831 class ModuleMapParser {
832 Lexer &L;
833 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000834
835 /// \brief Default target information, used only for string literal
836 /// parsing.
837 const TargetInfo *Target;
838
Douglas Gregora30cfe52011-11-11 19:10:28 +0000839 DiagnosticsEngine &Diags;
840 ModuleMap &Map;
841
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000842 /// \brief The directory that this module map resides in.
843 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000844
845 /// \brief The directory containing Clang-supplied headers.
846 const DirectoryEntry *BuiltinIncludeDir;
847
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000848 /// \brief Whether this module map is in a system header directory.
849 bool IsSystem;
850
Douglas Gregora30cfe52011-11-11 19:10:28 +0000851 /// \brief Whether an error occurred.
852 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000853
Douglas Gregora30cfe52011-11-11 19:10:28 +0000854 /// \brief Stores string data for the various string literals referenced
855 /// during parsing.
856 llvm::BumpPtrAllocator StringData;
857
858 /// \brief The current token.
859 MMToken Tok;
860
861 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000862 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000863
864 /// \brief Consume the current token and return its location.
865 SourceLocation consumeToken();
866
867 /// \brief Skip tokens until we reach the a token with the given kind
868 /// (or the end of the file).
869 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000870
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000871 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000872 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000873 void parseModuleDecl();
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000874 void parseExternModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000875 void parseRequiresDecl();
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000876 void parseHeaderDecl(clang::MMToken::TokenKind,
877 SourceLocation LeadingLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000878 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000879 void parseExportDecl();
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000880 void parseUseDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000881 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000882 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000883 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000884 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000885 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000886
Douglas Gregor6a1db482011-12-09 02:04:43 +0000887 const DirectoryEntry *getOverriddenHeaderSearchDir();
888
Douglas Gregora30cfe52011-11-11 19:10:28 +0000889 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000890 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000891 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000892 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000893 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000894 const DirectoryEntry *Directory,
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000895 const DirectoryEntry *BuiltinIncludeDir,
896 bool IsSystem)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000897 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000898 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
899 IsSystem(IsSystem), HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000900 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000901 Tok.clear();
902 consumeToken();
903 }
904
905 bool parseModuleMapFile();
906 };
907}
908
909SourceLocation ModuleMapParser::consumeToken() {
910retry:
911 SourceLocation Result = Tok.getLocation();
912 Tok.clear();
913
914 Token LToken;
915 L.LexFromRawLexer(LToken);
916 Tok.Location = LToken.getLocation().getRawEncoding();
917 switch (LToken.getKind()) {
918 case tok::raw_identifier:
919 Tok.StringData = LToken.getRawIdentifierData();
920 Tok.StringLength = LToken.getLength();
921 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000922 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000923 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000924 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000925 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000926 .Case("export", MMToken::ExportKeyword)
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000927 .Case("extern", MMToken::ExternKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000928 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000929 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000930 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000931 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000932 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000933 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000934 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000935 .Case("use", MMToken::UseKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000936 .Default(MMToken::Identifier);
937 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000938
939 case tok::comma:
940 Tok.Kind = MMToken::Comma;
941 break;
942
Douglas Gregora30cfe52011-11-11 19:10:28 +0000943 case tok::eof:
944 Tok.Kind = MMToken::EndOfFile;
945 break;
946
947 case tok::l_brace:
948 Tok.Kind = MMToken::LBrace;
949 break;
950
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000951 case tok::l_square:
952 Tok.Kind = MMToken::LSquare;
953 break;
954
Douglas Gregor90db2602011-12-02 01:47:07 +0000955 case tok::period:
956 Tok.Kind = MMToken::Period;
957 break;
958
Douglas Gregora30cfe52011-11-11 19:10:28 +0000959 case tok::r_brace:
960 Tok.Kind = MMToken::RBrace;
961 break;
962
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000963 case tok::r_square:
964 Tok.Kind = MMToken::RSquare;
965 break;
966
Douglas Gregor90db2602011-12-02 01:47:07 +0000967 case tok::star:
968 Tok.Kind = MMToken::Star;
969 break;
970
Richard Smith5794b532013-10-28 22:18:19 +0000971 case tok::exclaim:
972 Tok.Kind = MMToken::Exclaim;
973 break;
974
Douglas Gregora30cfe52011-11-11 19:10:28 +0000975 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000976 if (LToken.hasUDSuffix()) {
977 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
978 HadError = true;
979 goto retry;
980 }
981
Douglas Gregora30cfe52011-11-11 19:10:28 +0000982 // Parse the string literal.
983 LangOptions LangOpts;
984 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
985 if (StringLiteral.hadError)
986 goto retry;
987
988 // Copy the string literal into our string data allocator.
989 unsigned Length = StringLiteral.GetStringLength();
990 char *Saved = StringData.Allocate<char>(Length + 1);
991 memcpy(Saved, StringLiteral.GetString().data(), Length);
992 Saved[Length] = 0;
993
994 // Form the token.
995 Tok.Kind = MMToken::StringLiteral;
996 Tok.StringData = Saved;
997 Tok.StringLength = Length;
998 break;
999 }
1000
1001 case tok::comment:
1002 goto retry;
1003
1004 default:
1005 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1006 HadError = true;
1007 goto retry;
1008 }
1009
1010 return Result;
1011}
1012
1013void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1014 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001015 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001016 do {
1017 switch (Tok.Kind) {
1018 case MMToken::EndOfFile:
1019 return;
1020
1021 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001022 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +00001023 return;
1024
1025 ++braceDepth;
1026 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001027
1028 case MMToken::LSquare:
1029 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1030 return;
1031
1032 ++squareDepth;
1033 break;
1034
Douglas Gregora30cfe52011-11-11 19:10:28 +00001035 case MMToken::RBrace:
1036 if (braceDepth > 0)
1037 --braceDepth;
1038 else if (Tok.is(K))
1039 return;
1040 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001041
1042 case MMToken::RSquare:
1043 if (squareDepth > 0)
1044 --squareDepth;
1045 else if (Tok.is(K))
1046 return;
1047 break;
1048
Douglas Gregora30cfe52011-11-11 19:10:28 +00001049 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001050 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +00001051 return;
1052 break;
1053 }
1054
1055 consumeToken();
1056 } while (true);
1057}
1058
Douglas Gregor587986e2011-12-07 02:23:45 +00001059/// \brief Parse a module-id.
1060///
1061/// module-id:
1062/// identifier
1063/// identifier '.' module-id
1064///
1065/// \returns true if an error occurred, false otherwise.
1066bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1067 Id.clear();
1068 do {
1069 if (Tok.is(MMToken::Identifier)) {
1070 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1071 consumeToken();
1072 } else {
1073 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1074 return true;
1075 }
1076
1077 if (!Tok.is(MMToken::Period))
1078 break;
1079
1080 consumeToken();
1081 } while (true);
1082
1083 return false;
1084}
1085
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001086namespace {
1087 /// \brief Enumerates the known attributes.
1088 enum AttributeKind {
1089 /// \brief An unknown attribute.
1090 AT_unknown,
1091 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001092 AT_system,
1093 /// \brief The 'exhaustive' attribute.
1094 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001095 };
1096}
1097
Douglas Gregora30cfe52011-11-11 19:10:28 +00001098/// \brief Parse a module declaration.
1099///
1100/// module-declaration:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001101/// 'extern' 'module' module-id string-literal
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001102/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1103/// { module-member* }
1104///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001105/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001106/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001107/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001108/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001109/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001110/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001111///
1112/// submodule-declaration:
1113/// module-declaration
1114/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001115void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001116 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001117 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1118 if (Tok.is(MMToken::ExternKeyword)) {
1119 parseExternModuleDecl();
1120 return;
1121 }
1122
Douglas Gregord620a842011-12-06 17:16:41 +00001123 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001124 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001125 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001126 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001127
Douglas Gregord620a842011-12-06 17:16:41 +00001128 // Parse 'explicit' keyword, if present.
1129 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001130 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001131 Explicit = true;
1132 }
1133
1134 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001135 if (Tok.is(MMToken::FrameworkKeyword)) {
1136 consumeToken();
1137 Framework = true;
1138 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001139
1140 // Parse 'module' keyword.
1141 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001142 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001143 consumeToken();
1144 HadError = true;
1145 return;
1146 }
1147 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001148
1149 // If we have a wildcard for the module name, this is an inferred submodule.
1150 // Parse it.
1151 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001152 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001153
1154 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001155 ModuleId Id;
1156 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001157 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001158 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001159 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001160
Douglas Gregor587986e2011-12-07 02:23:45 +00001161 if (ActiveModule) {
1162 if (Id.size() > 1) {
1163 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1164 << SourceRange(Id.front().second, Id.back().second);
1165
1166 HadError = true;
1167 return;
1168 }
1169 } else if (Id.size() == 1 && Explicit) {
1170 // Top-level modules can't be explicit.
1171 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1172 Explicit = false;
1173 ExplicitLoc = SourceLocation();
1174 HadError = true;
1175 }
1176
1177 Module *PreviousActiveModule = ActiveModule;
1178 if (Id.size() > 1) {
1179 // This module map defines a submodule. Go find the module of which it
1180 // is a submodule.
1181 ActiveModule = 0;
1182 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1183 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1184 ActiveModule = Next;
1185 continue;
1186 }
1187
1188 if (ActiveModule) {
1189 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1190 << Id[I].first << ActiveModule->getTopLevelModule();
1191 } else {
1192 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1193 }
1194 HadError = true;
1195 return;
1196 }
1197 }
1198
1199 StringRef ModuleName = Id.back().first;
1200 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001201
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001202 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001203 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001204 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001205
Douglas Gregora30cfe52011-11-11 19:10:28 +00001206 // Parse the opening brace.
1207 if (!Tok.is(MMToken::LBrace)) {
1208 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1209 << ModuleName;
1210 HadError = true;
1211 return;
1212 }
1213 SourceLocation LBraceLoc = consumeToken();
1214
1215 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001216 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001217 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1218 // Skip the module definition.
1219 skipUntil(MMToken::RBrace);
1220 if (Tok.is(MMToken::RBrace))
1221 consumeToken();
1222 else {
1223 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1224 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1225 HadError = true;
1226 }
1227 return;
1228 }
1229
Douglas Gregora30cfe52011-11-11 19:10:28 +00001230 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1231 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001232 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001233
1234 // Skip the module definition.
1235 skipUntil(MMToken::RBrace);
1236 if (Tok.is(MMToken::RBrace))
1237 consumeToken();
1238
1239 HadError = true;
1240 return;
1241 }
1242
1243 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001244 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1245 Explicit).first;
1246 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001247 if (Attrs.IsSystem || IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001248 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001249
1250 bool Done = false;
1251 do {
1252 switch (Tok.Kind) {
1253 case MMToken::EndOfFile:
1254 case MMToken::RBrace:
1255 Done = true;
1256 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001257
1258 case MMToken::ConfigMacros:
1259 parseConfigMacros();
1260 break;
1261
Douglas Gregor906d66a2013-03-20 21:10:35 +00001262 case MMToken::Conflict:
1263 parseConflict();
1264 break;
1265
Douglas Gregora30cfe52011-11-11 19:10:28 +00001266 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001267 case MMToken::ExternKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001268 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001269 case MMToken::ModuleKeyword:
1270 parseModuleDecl();
1271 break;
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001272
Douglas Gregor90db2602011-12-02 01:47:07 +00001273 case MMToken::ExportKeyword:
1274 parseExportDecl();
1275 break;
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001276
1277 case MMToken::UseKeyword:
1278 parseUseDecl();
1279 break;
Douglas Gregor90db2602011-12-02 01:47:07 +00001280
Douglas Gregor51f564f2011-12-31 04:05:44 +00001281 case MMToken::RequiresKeyword:
1282 parseRequiresDecl();
1283 break;
1284
Douglas Gregor77d029f2011-12-08 19:11:24 +00001285 case MMToken::UmbrellaKeyword: {
1286 SourceLocation UmbrellaLoc = consumeToken();
1287 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001288 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +00001289 else
1290 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001291 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001292 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001293
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001294 case MMToken::ExcludeKeyword: {
1295 SourceLocation ExcludeLoc = consumeToken();
1296 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001297 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001298 } else {
1299 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1300 << "exclude";
1301 }
1302 break;
1303 }
1304
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001305 case MMToken::PrivateKeyword: {
1306 SourceLocation PrivateLoc = consumeToken();
1307 if (Tok.is(MMToken::HeaderKeyword)) {
1308 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1309 } else {
1310 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1311 << "private";
1312 }
1313 break;
1314 }
1315
Douglas Gregor489ad432011-12-08 18:00:48 +00001316 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001317 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001318 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001319
1320 case MMToken::LinkKeyword:
1321 parseLinkDecl();
1322 break;
1323
Douglas Gregora30cfe52011-11-11 19:10:28 +00001324 default:
1325 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1326 consumeToken();
1327 break;
1328 }
1329 } while (!Done);
1330
1331 if (Tok.is(MMToken::RBrace))
1332 consumeToken();
1333 else {
1334 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1335 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1336 HadError = true;
1337 }
1338
Douglas Gregor8767dc22013-01-14 17:57:51 +00001339 // If the active module is a top-level framework, and there are no link
1340 // libraries, automatically link against the framework.
1341 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1342 ActiveModule->LinkLibraries.empty()) {
1343 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1344 }
1345
Douglas Gregor587986e2011-12-07 02:23:45 +00001346 // We're done parsing this module. Pop back to the previous module.
1347 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001348}
Douglas Gregord620a842011-12-06 17:16:41 +00001349
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001350/// \brief Parse an extern module declaration.
1351///
1352/// extern module-declaration:
1353/// 'extern' 'module' module-id string-literal
1354void ModuleMapParser::parseExternModuleDecl() {
1355 assert(Tok.is(MMToken::ExternKeyword));
1356 consumeToken(); // 'extern' keyword
1357
1358 // Parse 'module' keyword.
1359 if (!Tok.is(MMToken::ModuleKeyword)) {
1360 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1361 consumeToken();
1362 HadError = true;
1363 return;
1364 }
1365 consumeToken(); // 'module' keyword
1366
1367 // Parse the module name.
1368 ModuleId Id;
1369 if (parseModuleId(Id)) {
1370 HadError = true;
1371 return;
1372 }
1373
1374 // Parse the referenced module map file name.
1375 if (!Tok.is(MMToken::StringLiteral)) {
1376 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1377 HadError = true;
1378 return;
1379 }
1380 std::string FileName = Tok.getString();
1381 consumeToken(); // filename
1382
1383 StringRef FileNameRef = FileName;
1384 SmallString<128> ModuleMapFileName;
1385 if (llvm::sys::path::is_relative(FileNameRef)) {
1386 ModuleMapFileName += Directory->getName();
1387 llvm::sys::path::append(ModuleMapFileName, FileName);
1388 FileNameRef = ModuleMapFileName.str();
1389 }
1390 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1391 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1392}
1393
Douglas Gregor51f564f2011-12-31 04:05:44 +00001394/// \brief Parse a requires declaration.
1395///
1396/// requires-declaration:
1397/// 'requires' feature-list
1398///
1399/// feature-list:
Richard Smith5794b532013-10-28 22:18:19 +00001400/// feature ',' feature-list
1401/// feature
1402///
1403/// feature:
1404/// '!'[opt] identifier
Douglas Gregor51f564f2011-12-31 04:05:44 +00001405void ModuleMapParser::parseRequiresDecl() {
1406 assert(Tok.is(MMToken::RequiresKeyword));
1407
1408 // Parse 'requires' keyword.
1409 consumeToken();
1410
1411 // Parse the feature-list.
1412 do {
Richard Smith5794b532013-10-28 22:18:19 +00001413 bool RequiredState = true;
1414 if (Tok.is(MMToken::Exclaim)) {
1415 RequiredState = false;
1416 consumeToken();
1417 }
1418
Douglas Gregor51f564f2011-12-31 04:05:44 +00001419 if (!Tok.is(MMToken::Identifier)) {
1420 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1421 HadError = true;
1422 return;
1423 }
1424
1425 // Consume the feature name.
1426 std::string Feature = Tok.getString();
1427 consumeToken();
1428
1429 // Add this feature.
Richard Smith5794b532013-10-28 22:18:19 +00001430 ActiveModule->addRequirement(Feature, RequiredState,
1431 Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001432
1433 if (!Tok.is(MMToken::Comma))
1434 break;
1435
1436 // Consume the comma.
1437 consumeToken();
1438 } while (true);
1439}
1440
Douglas Gregord620a842011-12-06 17:16:41 +00001441/// \brief Append to \p Paths the set of paths needed to get to the
1442/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001443static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001444 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001445 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001446 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001447 for (; Mod; Mod = Mod->Parent) {
1448 if (Mod->IsFramework)
1449 Paths.push_back(Mod->Name);
1450 }
1451
1452 if (Paths.empty())
1453 return;
1454
1455 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001456 for (unsigned I = Paths.size() - 1; I != 0; --I)
1457 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregord620a842011-12-06 17:16:41 +00001458}
1459
Douglas Gregora30cfe52011-11-11 19:10:28 +00001460/// \brief Parse a header declaration.
1461///
1462/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001463/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001464/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001465void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1466 SourceLocation LeadingLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001467 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001468 consumeToken();
1469
Douglas Gregora30cfe52011-11-11 19:10:28 +00001470 // Parse the header name.
1471 if (!Tok.is(MMToken::StringLiteral)) {
1472 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1473 << "header";
1474 HadError = true;
1475 return;
1476 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001477 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001478 SourceLocation FileNameLoc = consumeToken();
1479
Douglas Gregor77d029f2011-12-08 19:11:24 +00001480 // Check whether we already have an umbrella.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001481 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Douglas Gregor77d029f2011-12-08 19:11:24 +00001482 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1483 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001484 HadError = true;
1485 return;
1486 }
1487
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001488 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001489 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001490 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001491 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001492 if (llvm::sys::path::is_absolute(FileName)) {
1493 PathName = FileName;
1494 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001495 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1496 PathName = Dir->getName();
1497 llvm::sys::path::append(PathName, FileName);
1498 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001499 } else {
1500 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001501 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001502 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001503
Douglas Gregord620a842011-12-06 17:16:41 +00001504 if (ActiveModule->isPartOfFramework()) {
1505 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001506
1507 // Check whether this file is in the public headers.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001508 llvm::sys::path::append(PathName, "Headers", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001509 File = SourceMgr.getFileManager().getFile(PathName);
1510
1511 if (!File) {
1512 // Check whether this file is in the private headers.
1513 PathName.resize(PathLength);
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001514 llvm::sys::path::append(PathName, "PrivateHeaders", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001515 File = SourceMgr.getFileManager().getFile(PathName);
1516 }
1517 } else {
1518 // Lookup for normal headers.
1519 llvm::sys::path::append(PathName, FileName);
1520 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001521
1522 // If this is a system module with a top-level header, this header
1523 // may have a counterpart (or replacement) in the set of headers
1524 // supplied by Clang. Find that builtin header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001525 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1526 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1527 isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001528 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001529 llvm::sys::path::append(BuiltinPathName, FileName);
1530 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1531
1532 // If Clang supplies this header but the underlying system does not,
1533 // just silently swap in our builtin version. Otherwise, we'll end
1534 // up adding both (later).
1535 if (!File && BuiltinFile) {
1536 File = BuiltinFile;
1537 BuiltinFile = 0;
1538 }
1539 }
Douglas Gregord620a842011-12-06 17:16:41 +00001540 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001541 }
Douglas Gregora8654052011-11-17 22:09:43 +00001542
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001543 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1544 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001545 if (File) {
Daniel Jasperc6417092013-10-22 08:09:47 +00001546 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001547 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001548 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001549 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001550 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001551 HadError = true;
1552 } else {
1553 // Record this umbrella header.
1554 Map.setUmbrellaHeader(ActiveModule, File);
1555 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001556 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001557 // Record this header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001558 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1559 if (LeadingToken == MMToken::ExcludeKeyword)
1560 Role = ModuleMap::ExcludedHeader;
1561 else if (LeadingToken == MMToken::PrivateKeyword)
1562 Role = ModuleMap::PrivateHeader;
1563 else
1564 assert(LeadingToken == MMToken::HeaderKeyword);
1565
1566 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001567
1568 // If there is a builtin counterpart to this file, add it now.
1569 if (BuiltinFile)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001570 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001571 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001572 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor71f49f52012-11-15 19:47:16 +00001573 // Ignore excluded header files. They're optional anyway.
1574
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001575 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001576 << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001577 HadError = true;
1578 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001579}
1580
Douglas Gregor77d029f2011-12-08 19:11:24 +00001581/// \brief Parse an umbrella directory declaration.
1582///
1583/// umbrella-dir-declaration:
1584/// umbrella string-literal
1585void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1586 // Parse the directory name.
1587 if (!Tok.is(MMToken::StringLiteral)) {
1588 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1589 << "umbrella";
1590 HadError = true;
1591 return;
1592 }
1593
1594 std::string DirName = Tok.getString();
1595 SourceLocation DirNameLoc = consumeToken();
1596
1597 // Check whether we already have an umbrella.
1598 if (ActiveModule->Umbrella) {
1599 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1600 << ActiveModule->getFullModuleName();
1601 HadError = true;
1602 return;
1603 }
1604
1605 // Look for this file.
1606 const DirectoryEntry *Dir = 0;
1607 if (llvm::sys::path::is_absolute(DirName))
1608 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1609 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001610 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001611 PathName = Directory->getName();
1612 llvm::sys::path::append(PathName, DirName);
1613 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1614 }
1615
1616 if (!Dir) {
1617 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1618 << DirName;
1619 HadError = true;
1620 return;
1621 }
1622
1623 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1624 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1625 << OwningModule->getFullModuleName();
1626 HadError = true;
1627 return;
1628 }
1629
1630 // Record this umbrella directory.
1631 Map.setUmbrellaDir(ActiveModule, Dir);
1632}
1633
Douglas Gregor90db2602011-12-02 01:47:07 +00001634/// \brief Parse a module export declaration.
1635///
1636/// export-declaration:
1637/// 'export' wildcard-module-id
1638///
1639/// wildcard-module-id:
1640/// identifier
1641/// '*'
1642/// identifier '.' wildcard-module-id
1643void ModuleMapParser::parseExportDecl() {
1644 assert(Tok.is(MMToken::ExportKeyword));
1645 SourceLocation ExportLoc = consumeToken();
1646
1647 // Parse the module-id with an optional wildcard at the end.
1648 ModuleId ParsedModuleId;
1649 bool Wildcard = false;
1650 do {
1651 if (Tok.is(MMToken::Identifier)) {
1652 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1653 Tok.getLocation()));
1654 consumeToken();
1655
1656 if (Tok.is(MMToken::Period)) {
1657 consumeToken();
1658 continue;
1659 }
1660
1661 break;
1662 }
1663
1664 if(Tok.is(MMToken::Star)) {
1665 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001666 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001667 break;
1668 }
1669
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001670 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor90db2602011-12-02 01:47:07 +00001671 HadError = true;
1672 return;
1673 } while (true);
1674
1675 Module::UnresolvedExportDecl Unresolved = {
1676 ExportLoc, ParsedModuleId, Wildcard
1677 };
1678 ActiveModule->UnresolvedExports.push_back(Unresolved);
1679}
1680
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001681/// \brief Parse a module uses declaration.
1682///
1683/// uses-declaration:
1684/// 'uses' wildcard-module-id
1685void ModuleMapParser::parseUseDecl() {
1686 assert(Tok.is(MMToken::UseKeyword));
1687 consumeToken();
1688 // Parse the module-id.
1689 ModuleId ParsedModuleId;
1690
1691 do {
1692 if (Tok.is(MMToken::Identifier)) {
1693 ParsedModuleId.push_back(
1694 std::make_pair(Tok.getString(), Tok.getLocation()));
1695 consumeToken();
1696
1697 if (Tok.is(MMToken::Period)) {
1698 consumeToken();
1699 continue;
1700 }
1701
1702 break;
1703 }
1704
1705 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
1706 HadError = true;
1707 return;
1708 } while (true);
1709
1710 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1711}
1712
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001713/// \brief Parse a link declaration.
1714///
1715/// module-declaration:
1716/// 'link' 'framework'[opt] string-literal
1717void ModuleMapParser::parseLinkDecl() {
1718 assert(Tok.is(MMToken::LinkKeyword));
1719 SourceLocation LinkLoc = consumeToken();
1720
1721 // Parse the optional 'framework' keyword.
1722 bool IsFramework = false;
1723 if (Tok.is(MMToken::FrameworkKeyword)) {
1724 consumeToken();
1725 IsFramework = true;
1726 }
1727
1728 // Parse the library name
1729 if (!Tok.is(MMToken::StringLiteral)) {
1730 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1731 << IsFramework << SourceRange(LinkLoc);
1732 HadError = true;
1733 return;
1734 }
1735
1736 std::string LibraryName = Tok.getString();
1737 consumeToken();
1738 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1739 IsFramework));
1740}
1741
Douglas Gregor63a72682013-03-20 00:22:05 +00001742/// \brief Parse a configuration macro declaration.
1743///
1744/// module-declaration:
1745/// 'config_macros' attributes[opt] config-macro-list?
1746///
1747/// config-macro-list:
1748/// identifier (',' identifier)?
1749void ModuleMapParser::parseConfigMacros() {
1750 assert(Tok.is(MMToken::ConfigMacros));
1751 SourceLocation ConfigMacrosLoc = consumeToken();
1752
1753 // Only top-level modules can have configuration macros.
1754 if (ActiveModule->Parent) {
1755 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1756 }
1757
1758 // Parse the optional attributes.
1759 Attributes Attrs;
1760 parseOptionalAttributes(Attrs);
1761 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1762 ActiveModule->ConfigMacrosExhaustive = true;
1763 }
1764
1765 // If we don't have an identifier, we're done.
1766 if (!Tok.is(MMToken::Identifier))
1767 return;
1768
1769 // Consume the first identifier.
1770 if (!ActiveModule->Parent) {
1771 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1772 }
1773 consumeToken();
1774
1775 do {
1776 // If there's a comma, consume it.
1777 if (!Tok.is(MMToken::Comma))
1778 break;
1779 consumeToken();
1780
1781 // We expect to see a macro name here.
1782 if (!Tok.is(MMToken::Identifier)) {
1783 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1784 break;
1785 }
1786
1787 // Consume the macro name.
1788 if (!ActiveModule->Parent) {
1789 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1790 }
1791 consumeToken();
1792 } while (true);
1793}
1794
Douglas Gregor906d66a2013-03-20 21:10:35 +00001795/// \brief Format a module-id into a string.
1796static std::string formatModuleId(const ModuleId &Id) {
1797 std::string result;
1798 {
1799 llvm::raw_string_ostream OS(result);
1800
1801 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1802 if (I)
1803 OS << ".";
1804 OS << Id[I].first;
1805 }
1806 }
1807
1808 return result;
1809}
1810
1811/// \brief Parse a conflict declaration.
1812///
1813/// module-declaration:
1814/// 'conflict' module-id ',' string-literal
1815void ModuleMapParser::parseConflict() {
1816 assert(Tok.is(MMToken::Conflict));
1817 SourceLocation ConflictLoc = consumeToken();
1818 Module::UnresolvedConflict Conflict;
1819
1820 // Parse the module-id.
1821 if (parseModuleId(Conflict.Id))
1822 return;
1823
1824 // Parse the ','.
1825 if (!Tok.is(MMToken::Comma)) {
1826 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1827 << SourceRange(ConflictLoc);
1828 return;
1829 }
1830 consumeToken();
1831
1832 // Parse the message.
1833 if (!Tok.is(MMToken::StringLiteral)) {
1834 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1835 << formatModuleId(Conflict.Id);
1836 return;
1837 }
1838 Conflict.Message = Tok.getString().str();
1839 consumeToken();
1840
1841 // Add this unresolved conflict.
1842 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1843}
1844
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001845/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001846///
1847/// module-declaration:
1848/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1849/// { inferred-module-member* }
1850///
1851/// inferred-module-member:
1852/// 'export' '*'
1853/// 'exclude' identifier
1854void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001855 assert(Tok.is(MMToken::Star));
1856 SourceLocation StarLoc = consumeToken();
1857 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001858
Douglas Gregor1e123682011-12-05 22:27:44 +00001859 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001860 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001861 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1862 Failed = true;
1863 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001864
1865 if (ActiveModule) {
1866 // Inferred modules must have umbrella directories.
1867 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1868 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1869 Failed = true;
1870 }
1871
1872 // Check for redefinition of an inferred module.
1873 if (!Failed && ActiveModule->InferSubmodules) {
1874 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1875 if (ActiveModule->InferredSubmoduleLoc.isValid())
1876 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1877 diag::note_mmap_prev_definition);
1878 Failed = true;
1879 }
1880
1881 // Check for the 'framework' keyword, which is not permitted here.
1882 if (Framework) {
1883 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1884 Framework = false;
1885 }
1886 } else if (Explicit) {
1887 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1888 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001889 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001890
Douglas Gregor1e123682011-12-05 22:27:44 +00001891 // If there were any problems with this inferred submodule, skip its body.
1892 if (Failed) {
1893 if (Tok.is(MMToken::LBrace)) {
1894 consumeToken();
1895 skipUntil(MMToken::RBrace);
1896 if (Tok.is(MMToken::RBrace))
1897 consumeToken();
1898 }
1899 HadError = true;
1900 return;
1901 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001902
1903 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001904 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001905 parseOptionalAttributes(Attrs);
1906
1907 if (ActiveModule) {
1908 // Note that we have an inferred submodule.
1909 ActiveModule->InferSubmodules = true;
1910 ActiveModule->InferredSubmoduleLoc = StarLoc;
1911 ActiveModule->InferExplicitSubmodules = Explicit;
1912 } else {
1913 // We'll be inferring framework modules for this directory.
1914 Map.InferredDirectories[Directory].InferModules = true;
1915 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1916 }
1917
Douglas Gregor1e123682011-12-05 22:27:44 +00001918 // Parse the opening brace.
1919 if (!Tok.is(MMToken::LBrace)) {
1920 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1921 HadError = true;
1922 return;
1923 }
1924 SourceLocation LBraceLoc = consumeToken();
1925
1926 // Parse the body of the inferred submodule.
1927 bool Done = false;
1928 do {
1929 switch (Tok.Kind) {
1930 case MMToken::EndOfFile:
1931 case MMToken::RBrace:
1932 Done = true;
1933 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001934
1935 case MMToken::ExcludeKeyword: {
1936 if (ActiveModule) {
1937 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001938 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001939 consumeToken();
1940 break;
1941 }
1942
1943 consumeToken();
1944 if (!Tok.is(MMToken::Identifier)) {
1945 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1946 break;
1947 }
1948
1949 Map.InferredDirectories[Directory].ExcludedModules
1950 .push_back(Tok.getString());
1951 consumeToken();
1952 break;
1953 }
1954
1955 case MMToken::ExportKeyword:
1956 if (!ActiveModule) {
1957 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001958 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001959 consumeToken();
1960 break;
1961 }
1962
Douglas Gregor1e123682011-12-05 22:27:44 +00001963 consumeToken();
1964 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001965 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001966 else
1967 Diags.Report(Tok.getLocation(),
1968 diag::err_mmap_expected_export_wildcard);
1969 consumeToken();
1970 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001971
Douglas Gregor1e123682011-12-05 22:27:44 +00001972 case MMToken::ExplicitKeyword:
1973 case MMToken::ModuleKeyword:
1974 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001975 case MMToken::PrivateKeyword:
Douglas Gregor1e123682011-12-05 22:27:44 +00001976 case MMToken::UmbrellaKeyword:
1977 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001978 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001979 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001980 consumeToken();
1981 break;
1982 }
1983 } while (!Done);
1984
1985 if (Tok.is(MMToken::RBrace))
1986 consumeToken();
1987 else {
1988 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1989 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1990 HadError = true;
1991 }
1992}
1993
Douglas Gregor82e52372012-11-06 19:39:40 +00001994/// \brief Parse optional attributes.
1995///
1996/// attributes:
1997/// attribute attributes
1998/// attribute
1999///
2000/// attribute:
2001/// [ identifier ]
2002///
2003/// \param Attrs Will be filled in with the parsed attributes.
2004///
2005/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00002006bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00002007 bool HadError = false;
2008
2009 while (Tok.is(MMToken::LSquare)) {
2010 // Consume the '['.
2011 SourceLocation LSquareLoc = consumeToken();
2012
2013 // Check whether we have an attribute name here.
2014 if (!Tok.is(MMToken::Identifier)) {
2015 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2016 skipUntil(MMToken::RSquare);
2017 if (Tok.is(MMToken::RSquare))
2018 consumeToken();
2019 HadError = true;
2020 }
2021
2022 // Decode the attribute name.
2023 AttributeKind Attribute
2024 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00002025 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00002026 .Case("system", AT_system)
2027 .Default(AT_unknown);
2028 switch (Attribute) {
2029 case AT_unknown:
2030 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2031 << Tok.getString();
2032 break;
2033
2034 case AT_system:
2035 Attrs.IsSystem = true;
2036 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00002037
2038 case AT_exhaustive:
2039 Attrs.IsExhaustive = true;
2040 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00002041 }
2042 consumeToken();
2043
2044 // Consume the ']'.
2045 if (!Tok.is(MMToken::RSquare)) {
2046 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2047 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2048 skipUntil(MMToken::RSquare);
2049 HadError = true;
2050 }
2051
2052 if (Tok.is(MMToken::RSquare))
2053 consumeToken();
2054 }
2055
2056 return HadError;
2057}
2058
Douglas Gregor6a1db482011-12-09 02:04:43 +00002059/// \brief If there is a specific header search directory due the presence
2060/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
2061const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
2062 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
2063 // If we have an umbrella directory, use that.
2064 if (Mod->hasUmbrellaDir())
2065 return Mod->getUmbrellaDir();
2066
2067 // If we have a framework directory, stop looking.
2068 if (Mod->IsFramework)
2069 return 0;
2070 }
2071
2072 return 0;
2073}
2074
Douglas Gregora30cfe52011-11-11 19:10:28 +00002075/// \brief Parse a module map file.
2076///
2077/// module-map-file:
2078/// module-declaration*
2079bool ModuleMapParser::parseModuleMapFile() {
2080 do {
2081 switch (Tok.Kind) {
2082 case MMToken::EndOfFile:
2083 return HadError;
2084
Douglas Gregor587986e2011-12-07 02:23:45 +00002085 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00002086 case MMToken::ExternKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002087 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00002088 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002089 parseModuleDecl();
2090 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00002091
Douglas Gregor51f564f2011-12-31 04:05:44 +00002092 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00002093 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00002094 case MMToken::Conflict:
Richard Smith5794b532013-10-28 22:18:19 +00002095 case MMToken::Exclaim:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00002096 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00002097 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002098 case MMToken::HeaderKeyword:
2099 case MMToken::Identifier:
2100 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00002101 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00002102 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00002103 case MMToken::Period:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00002104 case MMToken::PrivateKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002105 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00002106 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00002107 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00002108 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002109 case MMToken::StringLiteral:
2110 case MMToken::UmbrellaKeyword:
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00002111 case MMToken::UseKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002112 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2113 HadError = true;
2114 consumeToken();
2115 break;
2116 }
2117 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002118}
2119
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002120bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor7005b902013-01-10 01:43:00 +00002121 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2122 = ParsedModuleMap.find(File);
2123 if (Known != ParsedModuleMap.end())
2124 return Known->second;
2125
Douglas Gregordc58aa72012-01-30 06:01:29 +00002126 assert(Target != 0 && "Missing target information");
Manuel Klimekee0cd372013-10-24 07:51:24 +00002127 FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
2128 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002129 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00002130 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00002131
2132 // Parse this module map file.
Manuel Klimekee0cd372013-10-24 07:51:24 +00002133 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Douglas Gregor51f564f2011-12-31 04:05:44 +00002134 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Manuel Klimekee0cd372013-10-24 07:51:24 +00002135 ModuleMapParser Parser(L, SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002136 BuiltinIncludeDir, IsSystem);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002137 bool Result = Parser.parseModuleMapFile();
2138 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00002139 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00002140 return Result;
2141}