blob: 54007c78d839fec5d6d05efd40e1b39b12a95dd8 [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,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000776 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000777 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000778 ExportKeyword,
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000779 ExternKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000780 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000781 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000782 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000783 Period,
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000784 PrivateKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000785 UmbrellaKeyword,
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000786 UseKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000787 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000788 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000789 StringLiteral,
790 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000791 RBrace,
792 LSquare,
793 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000794 } Kind;
795
796 unsigned Location;
797 unsigned StringLength;
798 const char *StringData;
799
800 void clear() {
801 Kind = EndOfFile;
802 Location = 0;
803 StringLength = 0;
804 StringData = 0;
805 }
806
807 bool is(TokenKind K) const { return Kind == K; }
808
809 SourceLocation getLocation() const {
810 return SourceLocation::getFromRawEncoding(Location);
811 }
812
813 StringRef getString() const {
814 return StringRef(StringData, StringLength);
815 }
816 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000817
818 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000819 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000820 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000821
822 /// \brief Whether this is a system module.
823 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000824
825 /// \brief Whether this is an exhaustive set of configuration macros.
826 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000827 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000828
Douglas Gregor82e52372012-11-06 19:39:40 +0000829
Douglas Gregora30cfe52011-11-11 19:10:28 +0000830 class ModuleMapParser {
831 Lexer &L;
832 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000833
834 /// \brief Default target information, used only for string literal
835 /// parsing.
836 const TargetInfo *Target;
837
Douglas Gregora30cfe52011-11-11 19:10:28 +0000838 DiagnosticsEngine &Diags;
839 ModuleMap &Map;
840
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000841 /// \brief The directory that this module map resides in.
842 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000843
844 /// \brief The directory containing Clang-supplied headers.
845 const DirectoryEntry *BuiltinIncludeDir;
846
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000847 /// \brief Whether this module map is in a system header directory.
848 bool IsSystem;
849
Douglas Gregora30cfe52011-11-11 19:10:28 +0000850 /// \brief Whether an error occurred.
851 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000852
Douglas Gregora30cfe52011-11-11 19:10:28 +0000853 /// \brief Stores string data for the various string literals referenced
854 /// during parsing.
855 llvm::BumpPtrAllocator StringData;
856
857 /// \brief The current token.
858 MMToken Tok;
859
860 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000861 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000862
863 /// \brief Consume the current token and return its location.
864 SourceLocation consumeToken();
865
866 /// \brief Skip tokens until we reach the a token with the given kind
867 /// (or the end of the file).
868 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000869
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000870 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000871 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000872 void parseModuleDecl();
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000873 void parseExternModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000874 void parseRequiresDecl();
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000875 void parseHeaderDecl(clang::MMToken::TokenKind,
876 SourceLocation LeadingLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000877 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000878 void parseExportDecl();
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000879 void parseUseDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000880 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000881 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000882 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000883 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000884 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000885
Douglas Gregor6a1db482011-12-09 02:04:43 +0000886 const DirectoryEntry *getOverriddenHeaderSearchDir();
887
Douglas Gregora30cfe52011-11-11 19:10:28 +0000888 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000889 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000890 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000891 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000892 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000893 const DirectoryEntry *Directory,
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000894 const DirectoryEntry *BuiltinIncludeDir,
895 bool IsSystem)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000896 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +0000897 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
898 IsSystem(IsSystem), HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000899 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000900 Tok.clear();
901 consumeToken();
902 }
903
904 bool parseModuleMapFile();
905 };
906}
907
908SourceLocation ModuleMapParser::consumeToken() {
909retry:
910 SourceLocation Result = Tok.getLocation();
911 Tok.clear();
912
913 Token LToken;
914 L.LexFromRawLexer(LToken);
915 Tok.Location = LToken.getLocation().getRawEncoding();
916 switch (LToken.getKind()) {
917 case tok::raw_identifier:
918 Tok.StringData = LToken.getRawIdentifierData();
919 Tok.StringLength = LToken.getLength();
920 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000921 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000922 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000923 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000924 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000925 .Case("export", MMToken::ExportKeyword)
Daniel Jasper5f0a3522013-09-11 07:20:44 +0000926 .Case("extern", MMToken::ExternKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000927 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000928 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000929 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000930 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +0000931 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000932 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000933 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperddd2dfc2013-09-24 09:14:14 +0000934 .Case("use", MMToken::UseKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000935 .Default(MMToken::Identifier);
936 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000937
938 case tok::comma:
939 Tok.Kind = MMToken::Comma;
940 break;
941
Douglas Gregora30cfe52011-11-11 19:10:28 +0000942 case tok::eof:
943 Tok.Kind = MMToken::EndOfFile;
944 break;
945
946 case tok::l_brace:
947 Tok.Kind = MMToken::LBrace;
948 break;
949
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000950 case tok::l_square:
951 Tok.Kind = MMToken::LSquare;
952 break;
953
Douglas Gregor90db2602011-12-02 01:47:07 +0000954 case tok::period:
955 Tok.Kind = MMToken::Period;
956 break;
957
Douglas Gregora30cfe52011-11-11 19:10:28 +0000958 case tok::r_brace:
959 Tok.Kind = MMToken::RBrace;
960 break;
961
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000962 case tok::r_square:
963 Tok.Kind = MMToken::RSquare;
964 break;
965
Douglas Gregor90db2602011-12-02 01:47:07 +0000966 case tok::star:
967 Tok.Kind = MMToken::Star;
968 break;
969
Douglas Gregora30cfe52011-11-11 19:10:28 +0000970 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000971 if (LToken.hasUDSuffix()) {
972 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
973 HadError = true;
974 goto retry;
975 }
976
Douglas Gregora30cfe52011-11-11 19:10:28 +0000977 // Parse the string literal.
978 LangOptions LangOpts;
979 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
980 if (StringLiteral.hadError)
981 goto retry;
982
983 // Copy the string literal into our string data allocator.
984 unsigned Length = StringLiteral.GetStringLength();
985 char *Saved = StringData.Allocate<char>(Length + 1);
986 memcpy(Saved, StringLiteral.GetString().data(), Length);
987 Saved[Length] = 0;
988
989 // Form the token.
990 Tok.Kind = MMToken::StringLiteral;
991 Tok.StringData = Saved;
992 Tok.StringLength = Length;
993 break;
994 }
995
996 case tok::comment:
997 goto retry;
998
999 default:
1000 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1001 HadError = true;
1002 goto retry;
1003 }
1004
1005 return Result;
1006}
1007
1008void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1009 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001010 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001011 do {
1012 switch (Tok.Kind) {
1013 case MMToken::EndOfFile:
1014 return;
1015
1016 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001017 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +00001018 return;
1019
1020 ++braceDepth;
1021 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001022
1023 case MMToken::LSquare:
1024 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1025 return;
1026
1027 ++squareDepth;
1028 break;
1029
Douglas Gregora30cfe52011-11-11 19:10:28 +00001030 case MMToken::RBrace:
1031 if (braceDepth > 0)
1032 --braceDepth;
1033 else if (Tok.is(K))
1034 return;
1035 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001036
1037 case MMToken::RSquare:
1038 if (squareDepth > 0)
1039 --squareDepth;
1040 else if (Tok.is(K))
1041 return;
1042 break;
1043
Douglas Gregora30cfe52011-11-11 19:10:28 +00001044 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001045 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +00001046 return;
1047 break;
1048 }
1049
1050 consumeToken();
1051 } while (true);
1052}
1053
Douglas Gregor587986e2011-12-07 02:23:45 +00001054/// \brief Parse a module-id.
1055///
1056/// module-id:
1057/// identifier
1058/// identifier '.' module-id
1059///
1060/// \returns true if an error occurred, false otherwise.
1061bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1062 Id.clear();
1063 do {
1064 if (Tok.is(MMToken::Identifier)) {
1065 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1066 consumeToken();
1067 } else {
1068 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1069 return true;
1070 }
1071
1072 if (!Tok.is(MMToken::Period))
1073 break;
1074
1075 consumeToken();
1076 } while (true);
1077
1078 return false;
1079}
1080
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001081namespace {
1082 /// \brief Enumerates the known attributes.
1083 enum AttributeKind {
1084 /// \brief An unknown attribute.
1085 AT_unknown,
1086 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001087 AT_system,
1088 /// \brief The 'exhaustive' attribute.
1089 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001090 };
1091}
1092
Douglas Gregora30cfe52011-11-11 19:10:28 +00001093/// \brief Parse a module declaration.
1094///
1095/// module-declaration:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001096/// 'extern' 'module' module-id string-literal
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001097/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1098/// { module-member* }
1099///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001100/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001101/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001102/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001103/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001104/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001105/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001106///
1107/// submodule-declaration:
1108/// module-declaration
1109/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001110void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001111 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001112 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1113 if (Tok.is(MMToken::ExternKeyword)) {
1114 parseExternModuleDecl();
1115 return;
1116 }
1117
Douglas Gregord620a842011-12-06 17:16:41 +00001118 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001119 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001120 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001121 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001122
Douglas Gregord620a842011-12-06 17:16:41 +00001123 // Parse 'explicit' keyword, if present.
1124 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001125 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001126 Explicit = true;
1127 }
1128
1129 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001130 if (Tok.is(MMToken::FrameworkKeyword)) {
1131 consumeToken();
1132 Framework = true;
1133 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001134
1135 // Parse 'module' keyword.
1136 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001137 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001138 consumeToken();
1139 HadError = true;
1140 return;
1141 }
1142 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001143
1144 // If we have a wildcard for the module name, this is an inferred submodule.
1145 // Parse it.
1146 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001147 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001148
1149 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001150 ModuleId Id;
1151 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001152 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001153 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001154 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001155
Douglas Gregor587986e2011-12-07 02:23:45 +00001156 if (ActiveModule) {
1157 if (Id.size() > 1) {
1158 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1159 << SourceRange(Id.front().second, Id.back().second);
1160
1161 HadError = true;
1162 return;
1163 }
1164 } else if (Id.size() == 1 && Explicit) {
1165 // Top-level modules can't be explicit.
1166 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1167 Explicit = false;
1168 ExplicitLoc = SourceLocation();
1169 HadError = true;
1170 }
1171
1172 Module *PreviousActiveModule = ActiveModule;
1173 if (Id.size() > 1) {
1174 // This module map defines a submodule. Go find the module of which it
1175 // is a submodule.
1176 ActiveModule = 0;
1177 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1178 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1179 ActiveModule = Next;
1180 continue;
1181 }
1182
1183 if (ActiveModule) {
1184 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1185 << Id[I].first << ActiveModule->getTopLevelModule();
1186 } else {
1187 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1188 }
1189 HadError = true;
1190 return;
1191 }
1192 }
1193
1194 StringRef ModuleName = Id.back().first;
1195 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001196
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001197 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001198 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001199 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001200
Douglas Gregora30cfe52011-11-11 19:10:28 +00001201 // Parse the opening brace.
1202 if (!Tok.is(MMToken::LBrace)) {
1203 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1204 << ModuleName;
1205 HadError = true;
1206 return;
1207 }
1208 SourceLocation LBraceLoc = consumeToken();
1209
1210 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001211 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001212 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1213 // Skip the module definition.
1214 skipUntil(MMToken::RBrace);
1215 if (Tok.is(MMToken::RBrace))
1216 consumeToken();
1217 else {
1218 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1219 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1220 HadError = true;
1221 }
1222 return;
1223 }
1224
Douglas Gregora30cfe52011-11-11 19:10:28 +00001225 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1226 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001227 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001228
1229 // Skip the module definition.
1230 skipUntil(MMToken::RBrace);
1231 if (Tok.is(MMToken::RBrace))
1232 consumeToken();
1233
1234 HadError = true;
1235 return;
1236 }
1237
1238 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001239 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1240 Explicit).first;
1241 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00001242 if (Attrs.IsSystem || IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001243 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001244
1245 bool Done = false;
1246 do {
1247 switch (Tok.Kind) {
1248 case MMToken::EndOfFile:
1249 case MMToken::RBrace:
1250 Done = true;
1251 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001252
1253 case MMToken::ConfigMacros:
1254 parseConfigMacros();
1255 break;
1256
Douglas Gregor906d66a2013-03-20 21:10:35 +00001257 case MMToken::Conflict:
1258 parseConflict();
1259 break;
1260
Douglas Gregora30cfe52011-11-11 19:10:28 +00001261 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001262 case MMToken::ExternKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001263 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001264 case MMToken::ModuleKeyword:
1265 parseModuleDecl();
1266 break;
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001267
Douglas Gregor90db2602011-12-02 01:47:07 +00001268 case MMToken::ExportKeyword:
1269 parseExportDecl();
1270 break;
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001271
1272 case MMToken::UseKeyword:
1273 parseUseDecl();
1274 break;
Douglas Gregor90db2602011-12-02 01:47:07 +00001275
Douglas Gregor51f564f2011-12-31 04:05:44 +00001276 case MMToken::RequiresKeyword:
1277 parseRequiresDecl();
1278 break;
1279
Douglas Gregor77d029f2011-12-08 19:11:24 +00001280 case MMToken::UmbrellaKeyword: {
1281 SourceLocation UmbrellaLoc = consumeToken();
1282 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001283 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +00001284 else
1285 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001286 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001287 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001288
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001289 case MMToken::ExcludeKeyword: {
1290 SourceLocation ExcludeLoc = consumeToken();
1291 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001292 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001293 } else {
1294 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1295 << "exclude";
1296 }
1297 break;
1298 }
1299
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001300 case MMToken::PrivateKeyword: {
1301 SourceLocation PrivateLoc = consumeToken();
1302 if (Tok.is(MMToken::HeaderKeyword)) {
1303 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1304 } else {
1305 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1306 << "private";
1307 }
1308 break;
1309 }
1310
Douglas Gregor489ad432011-12-08 18:00:48 +00001311 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001312 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001313 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001314
1315 case MMToken::LinkKeyword:
1316 parseLinkDecl();
1317 break;
1318
Douglas Gregora30cfe52011-11-11 19:10:28 +00001319 default:
1320 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1321 consumeToken();
1322 break;
1323 }
1324 } while (!Done);
1325
1326 if (Tok.is(MMToken::RBrace))
1327 consumeToken();
1328 else {
1329 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1330 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1331 HadError = true;
1332 }
1333
Douglas Gregor8767dc22013-01-14 17:57:51 +00001334 // If the active module is a top-level framework, and there are no link
1335 // libraries, automatically link against the framework.
1336 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1337 ActiveModule->LinkLibraries.empty()) {
1338 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1339 }
1340
Douglas Gregor587986e2011-12-07 02:23:45 +00001341 // We're done parsing this module. Pop back to the previous module.
1342 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001343}
Douglas Gregord620a842011-12-06 17:16:41 +00001344
Daniel Jasper5f0a3522013-09-11 07:20:44 +00001345/// \brief Parse an extern module declaration.
1346///
1347/// extern module-declaration:
1348/// 'extern' 'module' module-id string-literal
1349void ModuleMapParser::parseExternModuleDecl() {
1350 assert(Tok.is(MMToken::ExternKeyword));
1351 consumeToken(); // 'extern' keyword
1352
1353 // Parse 'module' keyword.
1354 if (!Tok.is(MMToken::ModuleKeyword)) {
1355 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1356 consumeToken();
1357 HadError = true;
1358 return;
1359 }
1360 consumeToken(); // 'module' keyword
1361
1362 // Parse the module name.
1363 ModuleId Id;
1364 if (parseModuleId(Id)) {
1365 HadError = true;
1366 return;
1367 }
1368
1369 // Parse the referenced module map file name.
1370 if (!Tok.is(MMToken::StringLiteral)) {
1371 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1372 HadError = true;
1373 return;
1374 }
1375 std::string FileName = Tok.getString();
1376 consumeToken(); // filename
1377
1378 StringRef FileNameRef = FileName;
1379 SmallString<128> ModuleMapFileName;
1380 if (llvm::sys::path::is_relative(FileNameRef)) {
1381 ModuleMapFileName += Directory->getName();
1382 llvm::sys::path::append(ModuleMapFileName, FileName);
1383 FileNameRef = ModuleMapFileName.str();
1384 }
1385 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1386 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1387}
1388
Douglas Gregor51f564f2011-12-31 04:05:44 +00001389/// \brief Parse a requires declaration.
1390///
1391/// requires-declaration:
1392/// 'requires' feature-list
1393///
1394/// feature-list:
1395/// identifier ',' feature-list
1396/// identifier
1397void ModuleMapParser::parseRequiresDecl() {
1398 assert(Tok.is(MMToken::RequiresKeyword));
1399
1400 // Parse 'requires' keyword.
1401 consumeToken();
1402
1403 // Parse the feature-list.
1404 do {
1405 if (!Tok.is(MMToken::Identifier)) {
1406 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1407 HadError = true;
1408 return;
1409 }
1410
1411 // Consume the feature name.
1412 std::string Feature = Tok.getString();
1413 consumeToken();
1414
1415 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001416 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001417
1418 if (!Tok.is(MMToken::Comma))
1419 break;
1420
1421 // Consume the comma.
1422 consumeToken();
1423 } while (true);
1424}
1425
Douglas Gregord620a842011-12-06 17:16:41 +00001426/// \brief Append to \p Paths the set of paths needed to get to the
1427/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001428static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001429 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001430 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001431 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001432 for (; Mod; Mod = Mod->Parent) {
1433 if (Mod->IsFramework)
1434 Paths.push_back(Mod->Name);
1435 }
1436
1437 if (Paths.empty())
1438 return;
1439
1440 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001441 for (unsigned I = Paths.size() - 1; I != 0; --I)
1442 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregord620a842011-12-06 17:16:41 +00001443}
1444
Douglas Gregora30cfe52011-11-11 19:10:28 +00001445/// \brief Parse a header declaration.
1446///
1447/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001448/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001449/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001450void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1451 SourceLocation LeadingLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001452 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001453 consumeToken();
1454
Douglas Gregora30cfe52011-11-11 19:10:28 +00001455 // Parse the header name.
1456 if (!Tok.is(MMToken::StringLiteral)) {
1457 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1458 << "header";
1459 HadError = true;
1460 return;
1461 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001462 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001463 SourceLocation FileNameLoc = consumeToken();
1464
Douglas Gregor77d029f2011-12-08 19:11:24 +00001465 // Check whether we already have an umbrella.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001466 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Douglas Gregor77d029f2011-12-08 19:11:24 +00001467 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1468 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001469 HadError = true;
1470 return;
1471 }
1472
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001473 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001474 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001475 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001476 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001477 if (llvm::sys::path::is_absolute(FileName)) {
1478 PathName = FileName;
1479 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001480 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1481 PathName = Dir->getName();
1482 llvm::sys::path::append(PathName, FileName);
1483 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001484 } else {
1485 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001486 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001487 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001488
Douglas Gregord620a842011-12-06 17:16:41 +00001489 if (ActiveModule->isPartOfFramework()) {
1490 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001491
1492 // Check whether this file is in the public headers.
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001493 llvm::sys::path::append(PathName, "Headers", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001494 File = SourceMgr.getFileManager().getFile(PathName);
1495
1496 if (!File) {
1497 // Check whether this file is in the private headers.
1498 PathName.resize(PathLength);
Benjamin Kramerceb6dc82013-06-28 16:25:46 +00001499 llvm::sys::path::append(PathName, "PrivateHeaders", FileName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001500 File = SourceMgr.getFileManager().getFile(PathName);
1501 }
1502 } else {
1503 // Lookup for normal headers.
1504 llvm::sys::path::append(PathName, FileName);
1505 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001506
1507 // If this is a system module with a top-level header, this header
1508 // may have a counterpart (or replacement) in the set of headers
1509 // supplied by Clang. Find that builtin header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001510 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1511 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1512 isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001513 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001514 llvm::sys::path::append(BuiltinPathName, FileName);
1515 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1516
1517 // If Clang supplies this header but the underlying system does not,
1518 // just silently swap in our builtin version. Otherwise, we'll end
1519 // up adding both (later).
1520 if (!File && BuiltinFile) {
1521 File = BuiltinFile;
1522 BuiltinFile = 0;
1523 }
1524 }
Douglas Gregord620a842011-12-06 17:16:41 +00001525 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001526 }
Douglas Gregora8654052011-11-17 22:09:43 +00001527
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001528 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1529 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001530 if (File) {
Daniel Jasperc6417092013-10-22 08:09:47 +00001531 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001532 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001533 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001534 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001535 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001536 HadError = true;
1537 } else {
1538 // Record this umbrella header.
1539 Map.setUmbrellaHeader(ActiveModule, File);
1540 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001541 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001542 // Record this header.
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001543 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1544 if (LeadingToken == MMToken::ExcludeKeyword)
1545 Role = ModuleMap::ExcludedHeader;
1546 else if (LeadingToken == MMToken::PrivateKeyword)
1547 Role = ModuleMap::PrivateHeader;
1548 else
1549 assert(LeadingToken == MMToken::HeaderKeyword);
1550
1551 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001552
1553 // If there is a builtin counterpart to this file, add it now.
1554 if (BuiltinFile)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001555 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001556 }
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001557 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor71f49f52012-11-15 19:47:16 +00001558 // Ignore excluded header files. They're optional anyway.
1559
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001560 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001561 << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001562 HadError = true;
1563 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001564}
1565
Douglas Gregor77d029f2011-12-08 19:11:24 +00001566/// \brief Parse an umbrella directory declaration.
1567///
1568/// umbrella-dir-declaration:
1569/// umbrella string-literal
1570void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1571 // Parse the directory name.
1572 if (!Tok.is(MMToken::StringLiteral)) {
1573 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1574 << "umbrella";
1575 HadError = true;
1576 return;
1577 }
1578
1579 std::string DirName = Tok.getString();
1580 SourceLocation DirNameLoc = consumeToken();
1581
1582 // Check whether we already have an umbrella.
1583 if (ActiveModule->Umbrella) {
1584 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1585 << ActiveModule->getFullModuleName();
1586 HadError = true;
1587 return;
1588 }
1589
1590 // Look for this file.
1591 const DirectoryEntry *Dir = 0;
1592 if (llvm::sys::path::is_absolute(DirName))
1593 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1594 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001595 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001596 PathName = Directory->getName();
1597 llvm::sys::path::append(PathName, DirName);
1598 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1599 }
1600
1601 if (!Dir) {
1602 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1603 << DirName;
1604 HadError = true;
1605 return;
1606 }
1607
1608 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1609 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1610 << OwningModule->getFullModuleName();
1611 HadError = true;
1612 return;
1613 }
1614
1615 // Record this umbrella directory.
1616 Map.setUmbrellaDir(ActiveModule, Dir);
1617}
1618
Douglas Gregor90db2602011-12-02 01:47:07 +00001619/// \brief Parse a module export declaration.
1620///
1621/// export-declaration:
1622/// 'export' wildcard-module-id
1623///
1624/// wildcard-module-id:
1625/// identifier
1626/// '*'
1627/// identifier '.' wildcard-module-id
1628void ModuleMapParser::parseExportDecl() {
1629 assert(Tok.is(MMToken::ExportKeyword));
1630 SourceLocation ExportLoc = consumeToken();
1631
1632 // Parse the module-id with an optional wildcard at the end.
1633 ModuleId ParsedModuleId;
1634 bool Wildcard = false;
1635 do {
1636 if (Tok.is(MMToken::Identifier)) {
1637 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1638 Tok.getLocation()));
1639 consumeToken();
1640
1641 if (Tok.is(MMToken::Period)) {
1642 consumeToken();
1643 continue;
1644 }
1645
1646 break;
1647 }
1648
1649 if(Tok.is(MMToken::Star)) {
1650 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001651 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001652 break;
1653 }
1654
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001655 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor90db2602011-12-02 01:47:07 +00001656 HadError = true;
1657 return;
1658 } while (true);
1659
1660 Module::UnresolvedExportDecl Unresolved = {
1661 ExportLoc, ParsedModuleId, Wildcard
1662 };
1663 ActiveModule->UnresolvedExports.push_back(Unresolved);
1664}
1665
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00001666/// \brief Parse a module uses declaration.
1667///
1668/// uses-declaration:
1669/// 'uses' wildcard-module-id
1670void ModuleMapParser::parseUseDecl() {
1671 assert(Tok.is(MMToken::UseKeyword));
1672 consumeToken();
1673 // Parse the module-id.
1674 ModuleId ParsedModuleId;
1675
1676 do {
1677 if (Tok.is(MMToken::Identifier)) {
1678 ParsedModuleId.push_back(
1679 std::make_pair(Tok.getString(), Tok.getLocation()));
1680 consumeToken();
1681
1682 if (Tok.is(MMToken::Period)) {
1683 consumeToken();
1684 continue;
1685 }
1686
1687 break;
1688 }
1689
1690 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
1691 HadError = true;
1692 return;
1693 } while (true);
1694
1695 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1696}
1697
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001698/// \brief Parse a link declaration.
1699///
1700/// module-declaration:
1701/// 'link' 'framework'[opt] string-literal
1702void ModuleMapParser::parseLinkDecl() {
1703 assert(Tok.is(MMToken::LinkKeyword));
1704 SourceLocation LinkLoc = consumeToken();
1705
1706 // Parse the optional 'framework' keyword.
1707 bool IsFramework = false;
1708 if (Tok.is(MMToken::FrameworkKeyword)) {
1709 consumeToken();
1710 IsFramework = true;
1711 }
1712
1713 // Parse the library name
1714 if (!Tok.is(MMToken::StringLiteral)) {
1715 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1716 << IsFramework << SourceRange(LinkLoc);
1717 HadError = true;
1718 return;
1719 }
1720
1721 std::string LibraryName = Tok.getString();
1722 consumeToken();
1723 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1724 IsFramework));
1725}
1726
Douglas Gregor63a72682013-03-20 00:22:05 +00001727/// \brief Parse a configuration macro declaration.
1728///
1729/// module-declaration:
1730/// 'config_macros' attributes[opt] config-macro-list?
1731///
1732/// config-macro-list:
1733/// identifier (',' identifier)?
1734void ModuleMapParser::parseConfigMacros() {
1735 assert(Tok.is(MMToken::ConfigMacros));
1736 SourceLocation ConfigMacrosLoc = consumeToken();
1737
1738 // Only top-level modules can have configuration macros.
1739 if (ActiveModule->Parent) {
1740 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1741 }
1742
1743 // Parse the optional attributes.
1744 Attributes Attrs;
1745 parseOptionalAttributes(Attrs);
1746 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1747 ActiveModule->ConfigMacrosExhaustive = true;
1748 }
1749
1750 // If we don't have an identifier, we're done.
1751 if (!Tok.is(MMToken::Identifier))
1752 return;
1753
1754 // Consume the first identifier.
1755 if (!ActiveModule->Parent) {
1756 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1757 }
1758 consumeToken();
1759
1760 do {
1761 // If there's a comma, consume it.
1762 if (!Tok.is(MMToken::Comma))
1763 break;
1764 consumeToken();
1765
1766 // We expect to see a macro name here.
1767 if (!Tok.is(MMToken::Identifier)) {
1768 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1769 break;
1770 }
1771
1772 // Consume the macro name.
1773 if (!ActiveModule->Parent) {
1774 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1775 }
1776 consumeToken();
1777 } while (true);
1778}
1779
Douglas Gregor906d66a2013-03-20 21:10:35 +00001780/// \brief Format a module-id into a string.
1781static std::string formatModuleId(const ModuleId &Id) {
1782 std::string result;
1783 {
1784 llvm::raw_string_ostream OS(result);
1785
1786 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1787 if (I)
1788 OS << ".";
1789 OS << Id[I].first;
1790 }
1791 }
1792
1793 return result;
1794}
1795
1796/// \brief Parse a conflict declaration.
1797///
1798/// module-declaration:
1799/// 'conflict' module-id ',' string-literal
1800void ModuleMapParser::parseConflict() {
1801 assert(Tok.is(MMToken::Conflict));
1802 SourceLocation ConflictLoc = consumeToken();
1803 Module::UnresolvedConflict Conflict;
1804
1805 // Parse the module-id.
1806 if (parseModuleId(Conflict.Id))
1807 return;
1808
1809 // Parse the ','.
1810 if (!Tok.is(MMToken::Comma)) {
1811 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1812 << SourceRange(ConflictLoc);
1813 return;
1814 }
1815 consumeToken();
1816
1817 // Parse the message.
1818 if (!Tok.is(MMToken::StringLiteral)) {
1819 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1820 << formatModuleId(Conflict.Id);
1821 return;
1822 }
1823 Conflict.Message = Tok.getString().str();
1824 consumeToken();
1825
1826 // Add this unresolved conflict.
1827 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1828}
1829
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001830/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001831///
1832/// module-declaration:
1833/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1834/// { inferred-module-member* }
1835///
1836/// inferred-module-member:
1837/// 'export' '*'
1838/// 'exclude' identifier
1839void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001840 assert(Tok.is(MMToken::Star));
1841 SourceLocation StarLoc = consumeToken();
1842 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001843
Douglas Gregor1e123682011-12-05 22:27:44 +00001844 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001845 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001846 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1847 Failed = true;
1848 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001849
1850 if (ActiveModule) {
1851 // Inferred modules must have umbrella directories.
1852 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1853 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1854 Failed = true;
1855 }
1856
1857 // Check for redefinition of an inferred module.
1858 if (!Failed && ActiveModule->InferSubmodules) {
1859 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1860 if (ActiveModule->InferredSubmoduleLoc.isValid())
1861 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1862 diag::note_mmap_prev_definition);
1863 Failed = true;
1864 }
1865
1866 // Check for the 'framework' keyword, which is not permitted here.
1867 if (Framework) {
1868 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1869 Framework = false;
1870 }
1871 } else if (Explicit) {
1872 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1873 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001874 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001875
Douglas Gregor1e123682011-12-05 22:27:44 +00001876 // If there were any problems with this inferred submodule, skip its body.
1877 if (Failed) {
1878 if (Tok.is(MMToken::LBrace)) {
1879 consumeToken();
1880 skipUntil(MMToken::RBrace);
1881 if (Tok.is(MMToken::RBrace))
1882 consumeToken();
1883 }
1884 HadError = true;
1885 return;
1886 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001887
1888 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001889 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001890 parseOptionalAttributes(Attrs);
1891
1892 if (ActiveModule) {
1893 // Note that we have an inferred submodule.
1894 ActiveModule->InferSubmodules = true;
1895 ActiveModule->InferredSubmoduleLoc = StarLoc;
1896 ActiveModule->InferExplicitSubmodules = Explicit;
1897 } else {
1898 // We'll be inferring framework modules for this directory.
1899 Map.InferredDirectories[Directory].InferModules = true;
1900 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1901 }
1902
Douglas Gregor1e123682011-12-05 22:27:44 +00001903 // Parse the opening brace.
1904 if (!Tok.is(MMToken::LBrace)) {
1905 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1906 HadError = true;
1907 return;
1908 }
1909 SourceLocation LBraceLoc = consumeToken();
1910
1911 // Parse the body of the inferred submodule.
1912 bool Done = false;
1913 do {
1914 switch (Tok.Kind) {
1915 case MMToken::EndOfFile:
1916 case MMToken::RBrace:
1917 Done = true;
1918 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001919
1920 case MMToken::ExcludeKeyword: {
1921 if (ActiveModule) {
1922 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001923 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001924 consumeToken();
1925 break;
1926 }
1927
1928 consumeToken();
1929 if (!Tok.is(MMToken::Identifier)) {
1930 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1931 break;
1932 }
1933
1934 Map.InferredDirectories[Directory].ExcludedModules
1935 .push_back(Tok.getString());
1936 consumeToken();
1937 break;
1938 }
1939
1940 case MMToken::ExportKeyword:
1941 if (!ActiveModule) {
1942 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001943 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001944 consumeToken();
1945 break;
1946 }
1947
Douglas Gregor1e123682011-12-05 22:27:44 +00001948 consumeToken();
1949 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001950 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001951 else
1952 Diags.Report(Tok.getLocation(),
1953 diag::err_mmap_expected_export_wildcard);
1954 consumeToken();
1955 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001956
Douglas Gregor1e123682011-12-05 22:27:44 +00001957 case MMToken::ExplicitKeyword:
1958 case MMToken::ModuleKeyword:
1959 case MMToken::HeaderKeyword:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00001960 case MMToken::PrivateKeyword:
Douglas Gregor1e123682011-12-05 22:27:44 +00001961 case MMToken::UmbrellaKeyword:
1962 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001963 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001964 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001965 consumeToken();
1966 break;
1967 }
1968 } while (!Done);
1969
1970 if (Tok.is(MMToken::RBrace))
1971 consumeToken();
1972 else {
1973 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1974 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1975 HadError = true;
1976 }
1977}
1978
Douglas Gregor82e52372012-11-06 19:39:40 +00001979/// \brief Parse optional attributes.
1980///
1981/// attributes:
1982/// attribute attributes
1983/// attribute
1984///
1985/// attribute:
1986/// [ identifier ]
1987///
1988/// \param Attrs Will be filled in with the parsed attributes.
1989///
1990/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001991bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001992 bool HadError = false;
1993
1994 while (Tok.is(MMToken::LSquare)) {
1995 // Consume the '['.
1996 SourceLocation LSquareLoc = consumeToken();
1997
1998 // Check whether we have an attribute name here.
1999 if (!Tok.is(MMToken::Identifier)) {
2000 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2001 skipUntil(MMToken::RSquare);
2002 if (Tok.is(MMToken::RSquare))
2003 consumeToken();
2004 HadError = true;
2005 }
2006
2007 // Decode the attribute name.
2008 AttributeKind Attribute
2009 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00002010 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00002011 .Case("system", AT_system)
2012 .Default(AT_unknown);
2013 switch (Attribute) {
2014 case AT_unknown:
2015 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2016 << Tok.getString();
2017 break;
2018
2019 case AT_system:
2020 Attrs.IsSystem = true;
2021 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00002022
2023 case AT_exhaustive:
2024 Attrs.IsExhaustive = true;
2025 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00002026 }
2027 consumeToken();
2028
2029 // Consume the ']'.
2030 if (!Tok.is(MMToken::RSquare)) {
2031 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2032 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2033 skipUntil(MMToken::RSquare);
2034 HadError = true;
2035 }
2036
2037 if (Tok.is(MMToken::RSquare))
2038 consumeToken();
2039 }
2040
2041 return HadError;
2042}
2043
Douglas Gregor6a1db482011-12-09 02:04:43 +00002044/// \brief If there is a specific header search directory due the presence
2045/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
2046const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
2047 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
2048 // If we have an umbrella directory, use that.
2049 if (Mod->hasUmbrellaDir())
2050 return Mod->getUmbrellaDir();
2051
2052 // If we have a framework directory, stop looking.
2053 if (Mod->IsFramework)
2054 return 0;
2055 }
2056
2057 return 0;
2058}
2059
Douglas Gregora30cfe52011-11-11 19:10:28 +00002060/// \brief Parse a module map file.
2061///
2062/// module-map-file:
2063/// module-declaration*
2064bool ModuleMapParser::parseModuleMapFile() {
2065 do {
2066 switch (Tok.Kind) {
2067 case MMToken::EndOfFile:
2068 return HadError;
2069
Douglas Gregor587986e2011-12-07 02:23:45 +00002070 case MMToken::ExplicitKeyword:
Daniel Jasper5f0a3522013-09-11 07:20:44 +00002071 case MMToken::ExternKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002072 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00002073 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002074 parseModuleDecl();
2075 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00002076
Douglas Gregor51f564f2011-12-31 04:05:44 +00002077 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00002078 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00002079 case MMToken::Conflict:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00002080 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00002081 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002082 case MMToken::HeaderKeyword:
2083 case MMToken::Identifier:
2084 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00002085 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00002086 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00002087 case MMToken::Period:
Lawrence Crowlbc3f6282013-06-20 21:14:14 +00002088 case MMToken::PrivateKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002089 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00002090 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00002091 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00002092 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002093 case MMToken::StringLiteral:
2094 case MMToken::UmbrellaKeyword:
Daniel Jasperddd2dfc2013-09-24 09:14:14 +00002095 case MMToken::UseKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00002096 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2097 HadError = true;
2098 consumeToken();
2099 break;
2100 }
2101 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002102}
2103
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002104bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor7005b902013-01-10 01:43:00 +00002105 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2106 = ParsedModuleMap.find(File);
2107 if (Known != ParsedModuleMap.end())
2108 return Known->second;
2109
Douglas Gregordc58aa72012-01-30 06:01:29 +00002110 assert(Target != 0 && "Missing target information");
Manuel Klimekee0cd372013-10-24 07:51:24 +00002111 FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
2112 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002113 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00002114 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00002115
2116 // Parse this module map file.
Manuel Klimekee0cd372013-10-24 07:51:24 +00002117 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Douglas Gregor51f564f2011-12-31 04:05:44 +00002118 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Manuel Klimekee0cd372013-10-24 07:51:24 +00002119 ModuleMapParser Parser(L, SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor8f5d7d12013-06-21 16:28:10 +00002120 BuiltinIncludeDir, IsSystem);
Douglas Gregora30cfe52011-11-11 19:10:28 +00002121 bool Result = Parser.parseModuleMapFile();
2122 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00002123 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00002124 return Result;
2125}