blob: 71a98e2152aca4ba334e296da28f47d1f1de5026 [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"
Douglas Gregor8b6d3de2011-11-11 21:55:48 +000030#include "llvm/Support/PathV2.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 Gregor90db2602011-12-02 01:47:07 +000048 // Find the starting module.
49 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
50 if (!Context) {
51 if (Complain)
52 Diags->Report(Unresolved.Id[0].second,
53 diag::err_mmap_missing_module_unqualified)
54 << Unresolved.Id[0].first << Mod->getFullModuleName();
55
56 return Module::ExportDecl();
57 }
58
59 // Dig into the module path.
60 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
61 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
62 Context);
63 if (!Sub) {
64 if (Complain)
65 Diags->Report(Unresolved.Id[I].second,
66 diag::err_mmap_missing_module_qualified)
67 << Unresolved.Id[I].first << Context->getFullModuleName()
68 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
69
70 return Module::ExportDecl();
71 }
72
73 Context = Sub;
74 }
75
76 return Module::ExportDecl(Context, Unresolved.Wildcard);
77}
78
Douglas Gregor51f564f2011-12-31 04:05:44 +000079ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000080 const LangOptions &LangOpts, const TargetInfo *Target,
81 HeaderSearch &HeaderInfo)
82 : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
83 BuiltinIncludeDir(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000084{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000085 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
86 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000087 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora30cfe52011-11-11 19:10:28 +000088 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
89 SourceMgr = new SourceManager(*Diags, FileMgr);
90}
91
92ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +000093 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
94 IEnd = Modules.end();
95 I != IEnd; ++I) {
96 delete I->getValue();
97 }
98
Douglas Gregora30cfe52011-11-11 19:10:28 +000099 delete SourceMgr;
100}
101
Douglas Gregordc58aa72012-01-30 06:01:29 +0000102void ModuleMap::setTarget(const TargetInfo &Target) {
103 assert((!this->Target || this->Target == &Target) &&
104 "Improper target override");
105 this->Target = &Target;
106}
107
Douglas Gregor8b48e082012-10-12 21:15:50 +0000108/// \brief "Sanitize" a filename so that it can be used as an identifier.
109static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
110 SmallVectorImpl<char> &Buffer) {
111 if (Name.empty())
112 return Name;
113
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000114 if (!isValidIdentifier(Name)) {
Douglas Gregor8b48e082012-10-12 21:15:50 +0000115 // If we don't already have something with the form of an identifier,
116 // create a buffer with the sanitized name.
117 Buffer.clear();
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000118 if (isDigit(Name[0]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000119 Buffer.push_back('_');
120 Buffer.reserve(Buffer.size() + Name.size());
121 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000122 if (isIdentifierBody(Name[I]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000123 Buffer.push_back(Name[I]);
124 else
125 Buffer.push_back('_');
126 }
127
128 Name = StringRef(Buffer.data(), Buffer.size());
129 }
130
131 while (llvm::StringSwitch<bool>(Name)
132#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
133#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
134#include "clang/Basic/TokenKinds.def"
135 .Default(false)) {
136 if (Name.data() != Buffer.data())
137 Buffer.append(Name.begin(), Name.end());
138 Buffer.push_back('_');
139 Name = StringRef(Buffer.data(), Buffer.size());
140 }
141
142 return Name;
143}
144
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000145Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000146 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000147 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000148 // If a header is not available, don't report that it maps to anything.
149 if (!Known->second.isAvailable())
Douglas Gregor51f564f2011-12-31 04:05:44 +0000150 return 0;
151
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000152 return Known->second.getModule();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000153 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000154
Douglas Gregoradb97992011-11-16 23:02:25 +0000155 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000156 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000157
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000158 // Note: as an egregious but useful hack we use the real path here, because
159 // frameworks moving from top-level frameworks to embedded frameworks tend
160 // to be symlinked from the top-level location to the embedded location,
161 // and we need to resolve lookups as if we had found the embedded location.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000162 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000163
164 // Keep walking up the directory hierarchy, looking for a directory with
165 // an umbrella header.
166 do {
167 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
168 = UmbrellaDirs.find(Dir);
169 if (KnownDir != UmbrellaDirs.end()) {
170 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000171
172 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000173 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000174 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000175 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000176 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000177
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000178 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000179 // Infer submodules for each of the directories we found between
180 // the directory of the umbrella header and the directory where
181 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000182 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000183
Douglas Gregor6a1db482011-12-09 02:04:43 +0000184 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000185 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000186 SmallString<32> NameBuf;
187 StringRef Name = sanitizeFilenameAsIdentifier(
188 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
189 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000190 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000191 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000192
193 // Associate the module and the directory.
194 UmbrellaDirs[SkippedDirs[I-1]] = Result;
195
196 // If inferred submodules export everything they import, add a
197 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000198 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000199 Result->Exports.push_back(Module::ExportDecl(0, true));
200 }
201
202 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000203 SmallString<32> NameBuf;
204 StringRef Name = sanitizeFilenameAsIdentifier(
205 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000206 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000207 Explicit).first;
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +0000208 Result->addTopHeader(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000209
210 // If inferred submodules export everything they import, add a
211 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000212 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000213 Result->Exports.push_back(Module::ExportDecl(0, true));
214 } else {
215 // Record each of the directories we stepped through as being part of
216 // the module we found, since the umbrella header covers them all.
217 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
218 UmbrellaDirs[SkippedDirs[I]] = Result;
219 }
220
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000221 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000222
223 // If a header corresponds to an unavailable module, don't report
224 // that it maps to anything.
225 if (!Result->isAvailable())
226 return 0;
227
Douglas Gregore209e502011-12-06 01:10:29 +0000228 return Result;
229 }
230
231 SkippedDirs.push_back(Dir);
232
Douglas Gregoradb97992011-11-16 23:02:25 +0000233 // Retrieve our parent path.
234 DirName = llvm::sys::path::parent_path(DirName);
235 if (DirName.empty())
236 break;
237
238 // Resolve the parent path to a directory entry.
239 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000240 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000241
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000242 return 0;
243}
244
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000245bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
246 HeadersMap::const_iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000247 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000248 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000249
250 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000251 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000252 StringRef DirName = Dir->getName();
253
254 // Keep walking up the directory hierarchy, looking for a directory with
255 // an umbrella header.
256 do {
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000257 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor51f564f2011-12-31 04:05:44 +0000258 = UmbrellaDirs.find(Dir);
259 if (KnownDir != UmbrellaDirs.end()) {
260 Module *Found = KnownDir->second;
261 if (!Found->isAvailable())
262 return true;
263
264 // Search up the module stack until we find a module with an umbrella
265 // directory.
266 Module *UmbrellaModule = Found;
267 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
268 UmbrellaModule = UmbrellaModule->Parent;
269
270 if (UmbrellaModule->InferSubmodules) {
271 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
272 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000273 SmallString<32> NameBuf;
274 StringRef Name = sanitizeFilenameAsIdentifier(
275 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
276 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000277 Found = lookupModuleQualified(Name, Found);
278 if (!Found)
279 return false;
280 if (!Found->isAvailable())
281 return true;
282 }
283
284 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000285 SmallString<32> NameBuf;
286 StringRef Name = sanitizeFilenameAsIdentifier(
287 llvm::sys::path::stem(Header->getName()),
288 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000289 Found = lookupModuleQualified(Name, Found);
290 if (!Found)
291 return false;
292 }
293
294 return !Found->isAvailable();
295 }
296
297 SkippedDirs.push_back(Dir);
298
299 // Retrieve our parent path.
300 DirName = llvm::sys::path::parent_path(DirName);
301 if (DirName.empty())
302 break;
303
304 // Resolve the parent path to a directory entry.
305 Dir = SourceMgr->getFileManager().getDirectory(DirName);
306 } while (Dir);
307
308 return false;
309}
310
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000311Module *ModuleMap::findModule(StringRef Name) const {
312 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor484535e2011-11-11 23:20:24 +0000313 if (Known != Modules.end())
314 return Known->getValue();
315
316 return 0;
317}
318
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000319Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
320 Module *Context) const {
Douglas Gregor90db2602011-12-02 01:47:07 +0000321 for(; Context; Context = Context->Parent) {
322 if (Module *Sub = lookupModuleQualified(Name, Context))
323 return Sub;
324 }
325
326 return findModule(Name);
327}
328
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000329Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor90db2602011-12-02 01:47:07 +0000330 if (!Context)
331 return findModule(Name);
332
Douglas Gregorb7a78192012-01-04 23:32:19 +0000333 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000334}
335
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000336std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000337ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
338 bool IsExplicit) {
339 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000340 if (Module *Sub = lookupModuleQualified(Name, Parent))
341 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000342
343 // Create a new module with this name.
344 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
345 IsExplicit);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000346 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000347 Modules[Name] = Result;
348 return std::make_pair(Result, true);
349}
350
Douglas Gregor82e52372012-11-06 19:39:40 +0000351bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000352 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000353 // Check whether we have already looked into the parent directory
354 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000355 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000356 inferred = InferredDirectories.find(ParentDir);
357 if (inferred == InferredDirectories.end())
358 return false;
359
360 if (!inferred->second.InferModules)
361 return false;
362
363 // We're allowed to infer for this directory, but make sure it's okay
364 // to infer this particular module.
365 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
366 inferred->second.ExcludedModules.end(),
367 Name) == inferred->second.ExcludedModules.end();
368
369 if (canInfer && inferred->second.InferSystemModules)
370 IsSystem = true;
371
372 return canInfer;
373}
374
Douglas Gregor8767dc22013-01-14 17:57:51 +0000375/// \brief For a framework module, infer the framework against which we
376/// should link.
377static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
378 FileManager &FileMgr) {
379 assert(Mod->IsFramework && "Can only infer linking for framework modules");
380 assert(!Mod->isSubFramework() &&
381 "Can only infer linking for top-level frameworks");
382
383 SmallString<128> LibName;
384 LibName += FrameworkDir->getName();
385 llvm::sys::path::append(LibName, Mod->Name);
386 if (FileMgr.getFile(LibName)) {
387 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
388 /*IsFramework=*/true));
389 }
390}
391
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000392Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000393ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000394 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000395 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000396 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000397 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000398 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
399 return Mod;
400
401 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000402
403 // If the framework has a parent path from which we're allowed to infer
404 // a framework module, do so.
405 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000406 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000407
Douglas Gregor7005b902013-01-10 01:43:00 +0000408 // Note: as an egregious but useful hack we use the real path here, because
409 // we might be looking at an embedded framework that symlinks out to a
410 // top-level framework, and we need to infer as if we were naming the
411 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000412 StringRef FrameworkDirName
413 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000414
Douglas Gregor82e52372012-11-06 19:39:40 +0000415 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000416 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000417 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000418 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000419 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
420 // Check whether we have already looked into the parent directory
421 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000422 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000423 inferred = InferredDirectories.find(ParentDir);
424 if (inferred == InferredDirectories.end()) {
425 // We haven't looked here before. Load a module map, if there is
426 // one.
427 SmallString<128> ModMapPath = Parent;
428 llvm::sys::path::append(ModMapPath, "module.map");
429 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
430 parseModuleMapFile(ModMapFile);
431 inferred = InferredDirectories.find(ParentDir);
432 }
433
434 if (inferred == InferredDirectories.end())
435 inferred = InferredDirectories.insert(
436 std::make_pair(ParentDir, InferredDirectory())).first;
437 }
438
439 if (inferred->second.InferModules) {
440 // We're allowed to infer for this directory, but make sure it's okay
441 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000442 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000443 canInfer = std::find(inferred->second.ExcludedModules.begin(),
444 inferred->second.ExcludedModules.end(),
445 Name) == inferred->second.ExcludedModules.end();
446
447 if (inferred->second.InferSystemModules)
448 IsSystem = true;
449 }
450 }
451 }
452
453 // If we're not allowed to infer a framework module, don't.
454 if (!canInfer)
455 return 0;
456 }
457
458
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000459 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000460 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000461 llvm::sys::path::append(UmbrellaName, "Headers");
462 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000463 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000464
465 // FIXME: If there's no umbrella header, we could probably scan the
466 // framework to load *everything*. But, it's not clear that this is a good
467 // idea.
468 if (!UmbrellaHeader)
469 return 0;
470
Douglas Gregorac252a32011-12-06 19:39:29 +0000471 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
472 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000473 if (IsSystem)
474 Result->IsSystem = IsSystem;
475
Douglas Gregorb7a78192012-01-04 23:32:19 +0000476 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000477 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000478
Douglas Gregor489ad432011-12-08 18:00:48 +0000479 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000480 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000481 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000482 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000483
484 // export *
485 Result->Exports.push_back(Module::ExportDecl(0, true));
486
Douglas Gregore209e502011-12-06 01:10:29 +0000487 // module * { export * }
488 Result->InferSubmodules = true;
489 Result->InferExportWildcard = true;
490
Douglas Gregorac252a32011-12-06 19:39:29 +0000491 // Look for subframeworks.
492 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000493 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000494 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000495 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000496 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000497 llvm::sys::path::native(SubframeworksDirName.str(),
498 SubframeworksDirNameNative);
499 for (llvm::sys::fs::directory_iterator
500 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000501 Dir != DirEnd && !EC; Dir.increment(EC)) {
502 if (!StringRef(Dir->path()).endswith(".framework"))
503 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000504
Douglas Gregorac252a32011-12-06 19:39:29 +0000505 if (const DirectoryEntry *SubframeworkDir
506 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000507 // Note: as an egregious but useful hack, we use the real path here and
508 // check whether it is actually a subdirectory of the parent directory.
509 // This will not be the case if the 'subframework' is actually a symlink
510 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000511 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
512 bool FoundParent = false;
513 do {
514 // Get the parent directory name.
515 SubframeworkDirName
516 = llvm::sys::path::parent_path(SubframeworkDirName);
517 if (SubframeworkDirName.empty())
518 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000519
Douglas Gregor713b7c02013-01-26 00:55:12 +0000520 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
521 FoundParent = true;
522 break;
523 }
524 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000525
Douglas Gregor713b7c02013-01-26 00:55:12 +0000526 if (!FoundParent)
527 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000528
Douglas Gregorac252a32011-12-06 19:39:29 +0000529 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000530 SmallString<32> NameBuf;
531 inferFrameworkModule(sanitizeFilenameAsIdentifier(
532 llvm::sys::path::stem(Dir->path()), NameBuf),
533 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000534 }
535 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000536
Douglas Gregor8767dc22013-01-14 17:57:51 +0000537 // If the module is a top-level framework, automatically link against the
538 // framework.
539 if (!Result->isSubFramework()) {
540 inferFrameworkLink(Result, FrameworkDir, FileMgr);
541 }
542
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000543 return Result;
544}
545
Douglas Gregore209e502011-12-06 01:10:29 +0000546void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000547 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000548 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000549 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000550}
551
Douglas Gregor77d029f2011-12-08 19:11:24 +0000552void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
553 Mod->Umbrella = UmbrellaDir;
554 UmbrellaDirs[UmbrellaDir] = Mod;
555}
556
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000557void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
558 bool Excluded) {
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000559 if (Excluded) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000560 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000561 } else {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000562 Mod->Headers.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000563 HeaderInfo.MarkFileModuleHeader(Header);
564 }
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000565 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000566}
567
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000568const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000569ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000570 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
571 return 0;
572
573 return SourceMgr->getFileEntryForID(
574 SourceMgr->getFileID(Module->DefinitionLoc));
575}
576
Douglas Gregora30cfe52011-11-11 19:10:28 +0000577void ModuleMap::dump() {
578 llvm::errs() << "Modules:";
579 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
580 MEnd = Modules.end();
581 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000582 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000583
584 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000585 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000586 H != HEnd; ++H) {
587 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000588 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000589 }
590}
591
Douglas Gregor90db2602011-12-02 01:47:07 +0000592bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
593 bool HadError = false;
594 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
595 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
596 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000597 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000598 Mod->Exports.push_back(Export);
599 else
600 HadError = true;
601 }
602 Mod->UnresolvedExports.clear();
603 return HadError;
604}
605
Douglas Gregor55988682011-12-05 16:33:54 +0000606Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
607 if (Loc.isInvalid())
608 return 0;
609
610 // Use the expansion location to determine which module we're in.
611 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
612 if (!ExpansionLoc.isFileID())
613 return 0;
614
615
616 const SourceManager &SrcMgr = Loc.getManager();
617 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000618
Douglas Gregor303aae92012-01-06 17:19:32 +0000619 while (const FileEntry *ExpansionFile
620 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
621 // Find the module that owns this header (if any).
622 if (Module *Mod = findModuleForHeader(ExpansionFile))
623 return Mod;
624
625 // No module owns this header, so look up the inclusion chain to see if
626 // any included header has an associated module.
627 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
628 if (IncludeLoc.isInvalid())
629 return 0;
630
631 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
632 }
633
634 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000635}
636
Douglas Gregora30cfe52011-11-11 19:10:28 +0000637//----------------------------------------------------------------------------//
638// Module map file parser
639//----------------------------------------------------------------------------//
640
641namespace clang {
642 /// \brief A token in a module map file.
643 struct MMToken {
644 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000645 Comma,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000646 EndOfFile,
647 HeaderKeyword,
648 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000649 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000650 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000651 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000652 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000653 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000654 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000655 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000656 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000657 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000658 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000659 StringLiteral,
660 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000661 RBrace,
662 LSquare,
663 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000664 } Kind;
665
666 unsigned Location;
667 unsigned StringLength;
668 const char *StringData;
669
670 void clear() {
671 Kind = EndOfFile;
672 Location = 0;
673 StringLength = 0;
674 StringData = 0;
675 }
676
677 bool is(TokenKind K) const { return Kind == K; }
678
679 SourceLocation getLocation() const {
680 return SourceLocation::getFromRawEncoding(Location);
681 }
682
683 StringRef getString() const {
684 return StringRef(StringData, StringLength);
685 }
686 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000687
688 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000689 struct Attributes {
690 Attributes() : IsSystem() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000691
692 /// \brief Whether this is a system module.
693 unsigned IsSystem : 1;
694 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000695
Douglas Gregor82e52372012-11-06 19:39:40 +0000696
Douglas Gregora30cfe52011-11-11 19:10:28 +0000697 class ModuleMapParser {
698 Lexer &L;
699 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000700
701 /// \brief Default target information, used only for string literal
702 /// parsing.
703 const TargetInfo *Target;
704
Douglas Gregora30cfe52011-11-11 19:10:28 +0000705 DiagnosticsEngine &Diags;
706 ModuleMap &Map;
707
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000708 /// \brief The directory that this module map resides in.
709 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000710
711 /// \brief The directory containing Clang-supplied headers.
712 const DirectoryEntry *BuiltinIncludeDir;
713
Douglas Gregora30cfe52011-11-11 19:10:28 +0000714 /// \brief Whether an error occurred.
715 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000716
Douglas Gregora30cfe52011-11-11 19:10:28 +0000717 /// \brief Stores string data for the various string literals referenced
718 /// during parsing.
719 llvm::BumpPtrAllocator StringData;
720
721 /// \brief The current token.
722 MMToken Tok;
723
724 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000725 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000726
727 /// \brief Consume the current token and return its location.
728 SourceLocation consumeToken();
729
730 /// \brief Skip tokens until we reach the a token with the given kind
731 /// (or the end of the file).
732 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000733
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000734 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000735 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000736 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000737 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000738 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000739 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000740 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000741 void parseLinkDecl();
Douglas Gregor82e52372012-11-06 19:39:40 +0000742 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000743 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000744
Douglas Gregor6a1db482011-12-09 02:04:43 +0000745 const DirectoryEntry *getOverriddenHeaderSearchDir();
746
Douglas Gregora30cfe52011-11-11 19:10:28 +0000747 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000748 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000749 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000750 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000751 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000752 const DirectoryEntry *Directory,
753 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000754 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000755 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
756 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000757 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000758 Tok.clear();
759 consumeToken();
760 }
761
762 bool parseModuleMapFile();
763 };
764}
765
766SourceLocation ModuleMapParser::consumeToken() {
767retry:
768 SourceLocation Result = Tok.getLocation();
769 Tok.clear();
770
771 Token LToken;
772 L.LexFromRawLexer(LToken);
773 Tok.Location = LToken.getLocation().getRawEncoding();
774 switch (LToken.getKind()) {
775 case tok::raw_identifier:
776 Tok.StringData = LToken.getRawIdentifierData();
777 Tok.StringLength = LToken.getLength();
778 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
779 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000780 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000781 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000782 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000783 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000784 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000785 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000786 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000787 .Case("umbrella", MMToken::UmbrellaKeyword)
788 .Default(MMToken::Identifier);
789 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000790
791 case tok::comma:
792 Tok.Kind = MMToken::Comma;
793 break;
794
Douglas Gregora30cfe52011-11-11 19:10:28 +0000795 case tok::eof:
796 Tok.Kind = MMToken::EndOfFile;
797 break;
798
799 case tok::l_brace:
800 Tok.Kind = MMToken::LBrace;
801 break;
802
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000803 case tok::l_square:
804 Tok.Kind = MMToken::LSquare;
805 break;
806
Douglas Gregor90db2602011-12-02 01:47:07 +0000807 case tok::period:
808 Tok.Kind = MMToken::Period;
809 break;
810
Douglas Gregora30cfe52011-11-11 19:10:28 +0000811 case tok::r_brace:
812 Tok.Kind = MMToken::RBrace;
813 break;
814
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000815 case tok::r_square:
816 Tok.Kind = MMToken::RSquare;
817 break;
818
Douglas Gregor90db2602011-12-02 01:47:07 +0000819 case tok::star:
820 Tok.Kind = MMToken::Star;
821 break;
822
Douglas Gregora30cfe52011-11-11 19:10:28 +0000823 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000824 if (LToken.hasUDSuffix()) {
825 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
826 HadError = true;
827 goto retry;
828 }
829
Douglas Gregora30cfe52011-11-11 19:10:28 +0000830 // Parse the string literal.
831 LangOptions LangOpts;
832 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
833 if (StringLiteral.hadError)
834 goto retry;
835
836 // Copy the string literal into our string data allocator.
837 unsigned Length = StringLiteral.GetStringLength();
838 char *Saved = StringData.Allocate<char>(Length + 1);
839 memcpy(Saved, StringLiteral.GetString().data(), Length);
840 Saved[Length] = 0;
841
842 // Form the token.
843 Tok.Kind = MMToken::StringLiteral;
844 Tok.StringData = Saved;
845 Tok.StringLength = Length;
846 break;
847 }
848
849 case tok::comment:
850 goto retry;
851
852 default:
853 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
854 HadError = true;
855 goto retry;
856 }
857
858 return Result;
859}
860
861void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
862 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000863 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000864 do {
865 switch (Tok.Kind) {
866 case MMToken::EndOfFile:
867 return;
868
869 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000870 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000871 return;
872
873 ++braceDepth;
874 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000875
876 case MMToken::LSquare:
877 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
878 return;
879
880 ++squareDepth;
881 break;
882
Douglas Gregora30cfe52011-11-11 19:10:28 +0000883 case MMToken::RBrace:
884 if (braceDepth > 0)
885 --braceDepth;
886 else if (Tok.is(K))
887 return;
888 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000889
890 case MMToken::RSquare:
891 if (squareDepth > 0)
892 --squareDepth;
893 else if (Tok.is(K))
894 return;
895 break;
896
Douglas Gregora30cfe52011-11-11 19:10:28 +0000897 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000898 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000899 return;
900 break;
901 }
902
903 consumeToken();
904 } while (true);
905}
906
Douglas Gregor587986e2011-12-07 02:23:45 +0000907/// \brief Parse a module-id.
908///
909/// module-id:
910/// identifier
911/// identifier '.' module-id
912///
913/// \returns true if an error occurred, false otherwise.
914bool ModuleMapParser::parseModuleId(ModuleId &Id) {
915 Id.clear();
916 do {
917 if (Tok.is(MMToken::Identifier)) {
918 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
919 consumeToken();
920 } else {
921 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
922 return true;
923 }
924
925 if (!Tok.is(MMToken::Period))
926 break;
927
928 consumeToken();
929 } while (true);
930
931 return false;
932}
933
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000934namespace {
935 /// \brief Enumerates the known attributes.
936 enum AttributeKind {
937 /// \brief An unknown attribute.
938 AT_unknown,
939 /// \brief The 'system' attribute.
940 AT_system
941 };
942}
943
Douglas Gregora30cfe52011-11-11 19:10:28 +0000944/// \brief Parse a module declaration.
945///
946/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000947/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
948/// { module-member* }
949///
Douglas Gregora30cfe52011-11-11 19:10:28 +0000950/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +0000951/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000952/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +0000953/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +0000954/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000955/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +0000956///
957/// submodule-declaration:
958/// module-declaration
959/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000960void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +0000961 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
962 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +0000963 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +0000964 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000965 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +0000966 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +0000967
Douglas Gregord620a842011-12-06 17:16:41 +0000968 // Parse 'explicit' keyword, if present.
969 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +0000970 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +0000971 Explicit = true;
972 }
973
974 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +0000975 if (Tok.is(MMToken::FrameworkKeyword)) {
976 consumeToken();
977 Framework = true;
978 }
Douglas Gregora30cfe52011-11-11 19:10:28 +0000979
980 // Parse 'module' keyword.
981 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +0000982 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000983 consumeToken();
984 HadError = true;
985 return;
986 }
987 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +0000988
989 // If we have a wildcard for the module name, this is an inferred submodule.
990 // Parse it.
991 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +0000992 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000993
994 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +0000995 ModuleId Id;
996 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000997 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +0000998 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000999 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001000
Douglas Gregor587986e2011-12-07 02:23:45 +00001001 if (ActiveModule) {
1002 if (Id.size() > 1) {
1003 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1004 << SourceRange(Id.front().second, Id.back().second);
1005
1006 HadError = true;
1007 return;
1008 }
1009 } else if (Id.size() == 1 && Explicit) {
1010 // Top-level modules can't be explicit.
1011 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1012 Explicit = false;
1013 ExplicitLoc = SourceLocation();
1014 HadError = true;
1015 }
1016
1017 Module *PreviousActiveModule = ActiveModule;
1018 if (Id.size() > 1) {
1019 // This module map defines a submodule. Go find the module of which it
1020 // is a submodule.
1021 ActiveModule = 0;
1022 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1023 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1024 ActiveModule = Next;
1025 continue;
1026 }
1027
1028 if (ActiveModule) {
1029 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1030 << Id[I].first << ActiveModule->getTopLevelModule();
1031 } else {
1032 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1033 }
1034 HadError = true;
1035 return;
1036 }
1037 }
1038
1039 StringRef ModuleName = Id.back().first;
1040 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001041
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001042 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001043 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001044 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001045
Douglas Gregora30cfe52011-11-11 19:10:28 +00001046 // Parse the opening brace.
1047 if (!Tok.is(MMToken::LBrace)) {
1048 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1049 << ModuleName;
1050 HadError = true;
1051 return;
1052 }
1053 SourceLocation LBraceLoc = consumeToken();
1054
1055 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001056 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001057 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1058 // Skip the module definition.
1059 skipUntil(MMToken::RBrace);
1060 if (Tok.is(MMToken::RBrace))
1061 consumeToken();
1062 else {
1063 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1064 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1065 HadError = true;
1066 }
1067 return;
1068 }
1069
Douglas Gregora30cfe52011-11-11 19:10:28 +00001070 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1071 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001072 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001073
1074 // Skip the module definition.
1075 skipUntil(MMToken::RBrace);
1076 if (Tok.is(MMToken::RBrace))
1077 consumeToken();
1078
1079 HadError = true;
1080 return;
1081 }
1082
1083 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001084 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1085 Explicit).first;
1086 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001087 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001088 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001089
1090 bool Done = false;
1091 do {
1092 switch (Tok.Kind) {
1093 case MMToken::EndOfFile:
1094 case MMToken::RBrace:
1095 Done = true;
1096 break;
1097
1098 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001099 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001100 case MMToken::ModuleKeyword:
1101 parseModuleDecl();
1102 break;
1103
Douglas Gregor90db2602011-12-02 01:47:07 +00001104 case MMToken::ExportKeyword:
1105 parseExportDecl();
1106 break;
1107
Douglas Gregor51f564f2011-12-31 04:05:44 +00001108 case MMToken::RequiresKeyword:
1109 parseRequiresDecl();
1110 break;
1111
Douglas Gregor77d029f2011-12-08 19:11:24 +00001112 case MMToken::UmbrellaKeyword: {
1113 SourceLocation UmbrellaLoc = consumeToken();
1114 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001115 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001116 else
1117 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001118 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001119 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001120
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001121 case MMToken::ExcludeKeyword: {
1122 SourceLocation ExcludeLoc = consumeToken();
1123 if (Tok.is(MMToken::HeaderKeyword)) {
1124 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1125 } else {
1126 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1127 << "exclude";
1128 }
1129 break;
1130 }
1131
Douglas Gregor489ad432011-12-08 18:00:48 +00001132 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001133 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001134 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001135
1136 case MMToken::LinkKeyword:
1137 parseLinkDecl();
1138 break;
1139
Douglas Gregora30cfe52011-11-11 19:10:28 +00001140 default:
1141 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1142 consumeToken();
1143 break;
1144 }
1145 } while (!Done);
1146
1147 if (Tok.is(MMToken::RBrace))
1148 consumeToken();
1149 else {
1150 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1151 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1152 HadError = true;
1153 }
1154
Douglas Gregor8767dc22013-01-14 17:57:51 +00001155 // If the active module is a top-level framework, and there are no link
1156 // libraries, automatically link against the framework.
1157 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1158 ActiveModule->LinkLibraries.empty()) {
1159 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1160 }
1161
Douglas Gregor587986e2011-12-07 02:23:45 +00001162 // We're done parsing this module. Pop back to the previous module.
1163 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001164}
Douglas Gregord620a842011-12-06 17:16:41 +00001165
Douglas Gregor51f564f2011-12-31 04:05:44 +00001166/// \brief Parse a requires declaration.
1167///
1168/// requires-declaration:
1169/// 'requires' feature-list
1170///
1171/// feature-list:
1172/// identifier ',' feature-list
1173/// identifier
1174void ModuleMapParser::parseRequiresDecl() {
1175 assert(Tok.is(MMToken::RequiresKeyword));
1176
1177 // Parse 'requires' keyword.
1178 consumeToken();
1179
1180 // Parse the feature-list.
1181 do {
1182 if (!Tok.is(MMToken::Identifier)) {
1183 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1184 HadError = true;
1185 return;
1186 }
1187
1188 // Consume the feature name.
1189 std::string Feature = Tok.getString();
1190 consumeToken();
1191
1192 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001193 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001194
1195 if (!Tok.is(MMToken::Comma))
1196 break;
1197
1198 // Consume the comma.
1199 consumeToken();
1200 } while (true);
1201}
1202
Douglas Gregord620a842011-12-06 17:16:41 +00001203/// \brief Append to \p Paths the set of paths needed to get to the
1204/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001205static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001206 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001207 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001208 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001209 for (; Mod; Mod = Mod->Parent) {
1210 if (Mod->IsFramework)
1211 Paths.push_back(Mod->Name);
1212 }
1213
1214 if (Paths.empty())
1215 return;
1216
1217 // Add Frameworks/Name.framework for each subframework.
1218 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1219 llvm::sys::path::append(Path, "Frameworks");
1220 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1221 }
1222}
1223
Douglas Gregor2f04f182012-02-02 18:42:48 +00001224/// \brief Determine whether the given file name is the name of a builtin
1225/// header, supplied by Clang to replace, override, or augment existing system
1226/// headers.
1227static bool isBuiltinHeader(StringRef FileName) {
1228 return llvm::StringSwitch<bool>(FileName)
1229 .Case("float.h", true)
1230 .Case("iso646.h", true)
1231 .Case("limits.h", true)
1232 .Case("stdalign.h", true)
1233 .Case("stdarg.h", true)
1234 .Case("stdbool.h", true)
1235 .Case("stddef.h", true)
1236 .Case("stdint.h", true)
1237 .Case("tgmath.h", true)
1238 .Case("unwind.h", true)
1239 .Default(false);
1240}
1241
Douglas Gregora30cfe52011-11-11 19:10:28 +00001242/// \brief Parse a header declaration.
1243///
1244/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001245/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001246/// 'exclude'[opt] 'header' string-literal
1247void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1248 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001249 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001250 consumeToken();
1251
Douglas Gregor489ad432011-12-08 18:00:48 +00001252 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001253 bool Exclude = ExcludeLoc.isValid();
1254 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001255 // Parse the header name.
1256 if (!Tok.is(MMToken::StringLiteral)) {
1257 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1258 << "header";
1259 HadError = true;
1260 return;
1261 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001262 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001263 SourceLocation FileNameLoc = consumeToken();
1264
Douglas Gregor77d029f2011-12-08 19:11:24 +00001265 // Check whether we already have an umbrella.
1266 if (Umbrella && ActiveModule->Umbrella) {
1267 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1268 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001269 HadError = true;
1270 return;
1271 }
1272
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001273 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001274 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001275 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001276 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001277 if (llvm::sys::path::is_absolute(FileName)) {
1278 PathName = FileName;
1279 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001280 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1281 PathName = Dir->getName();
1282 llvm::sys::path::append(PathName, FileName);
1283 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001284 } else {
1285 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001286 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001287 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001288
Douglas Gregord620a842011-12-06 17:16:41 +00001289 if (ActiveModule->isPartOfFramework()) {
1290 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001291
1292 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001293 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001294 llvm::sys::path::append(PathName, FileName);
1295 File = SourceMgr.getFileManager().getFile(PathName);
1296
1297 if (!File) {
1298 // Check whether this file is in the private headers.
1299 PathName.resize(PathLength);
1300 llvm::sys::path::append(PathName, "PrivateHeaders");
1301 llvm::sys::path::append(PathName, FileName);
1302 File = SourceMgr.getFileManager().getFile(PathName);
1303 }
1304 } else {
1305 // Lookup for normal headers.
1306 llvm::sys::path::append(PathName, FileName);
1307 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001308
1309 // If this is a system module with a top-level header, this header
1310 // may have a counterpart (or replacement) in the set of headers
1311 // supplied by Clang. Find that builtin header.
1312 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1313 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001314 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001315 llvm::sys::path::append(BuiltinPathName, FileName);
1316 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1317
1318 // If Clang supplies this header but the underlying system does not,
1319 // just silently swap in our builtin version. Otherwise, we'll end
1320 // up adding both (later).
1321 if (!File && BuiltinFile) {
1322 File = BuiltinFile;
1323 BuiltinFile = 0;
1324 }
1325 }
Douglas Gregord620a842011-12-06 17:16:41 +00001326 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001327 }
Douglas Gregora8654052011-11-17 22:09:43 +00001328
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001329 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1330 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001331 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001332 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001333 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001334 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001335 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001336 } else if (Umbrella) {
1337 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001338 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001339 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001340 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001341 HadError = true;
1342 } else {
1343 // Record this umbrella header.
1344 Map.setUmbrellaHeader(ActiveModule, File);
1345 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001346 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001347 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001348 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001349
1350 // If there is a builtin counterpart to this file, add it now.
1351 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001352 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001353 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001354 } else if (!Exclude) {
1355 // Ignore excluded header files. They're optional anyway.
1356
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001357 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001358 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001359 HadError = true;
1360 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001361}
1362
Douglas Gregor77d029f2011-12-08 19:11:24 +00001363/// \brief Parse an umbrella directory declaration.
1364///
1365/// umbrella-dir-declaration:
1366/// umbrella string-literal
1367void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1368 // Parse the directory name.
1369 if (!Tok.is(MMToken::StringLiteral)) {
1370 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1371 << "umbrella";
1372 HadError = true;
1373 return;
1374 }
1375
1376 std::string DirName = Tok.getString();
1377 SourceLocation DirNameLoc = consumeToken();
1378
1379 // Check whether we already have an umbrella.
1380 if (ActiveModule->Umbrella) {
1381 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1382 << ActiveModule->getFullModuleName();
1383 HadError = true;
1384 return;
1385 }
1386
1387 // Look for this file.
1388 const DirectoryEntry *Dir = 0;
1389 if (llvm::sys::path::is_absolute(DirName))
1390 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1391 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001392 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001393 PathName = Directory->getName();
1394 llvm::sys::path::append(PathName, DirName);
1395 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1396 }
1397
1398 if (!Dir) {
1399 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1400 << DirName;
1401 HadError = true;
1402 return;
1403 }
1404
1405 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1406 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1407 << OwningModule->getFullModuleName();
1408 HadError = true;
1409 return;
1410 }
1411
1412 // Record this umbrella directory.
1413 Map.setUmbrellaDir(ActiveModule, Dir);
1414}
1415
Douglas Gregor90db2602011-12-02 01:47:07 +00001416/// \brief Parse a module export declaration.
1417///
1418/// export-declaration:
1419/// 'export' wildcard-module-id
1420///
1421/// wildcard-module-id:
1422/// identifier
1423/// '*'
1424/// identifier '.' wildcard-module-id
1425void ModuleMapParser::parseExportDecl() {
1426 assert(Tok.is(MMToken::ExportKeyword));
1427 SourceLocation ExportLoc = consumeToken();
1428
1429 // Parse the module-id with an optional wildcard at the end.
1430 ModuleId ParsedModuleId;
1431 bool Wildcard = false;
1432 do {
1433 if (Tok.is(MMToken::Identifier)) {
1434 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1435 Tok.getLocation()));
1436 consumeToken();
1437
1438 if (Tok.is(MMToken::Period)) {
1439 consumeToken();
1440 continue;
1441 }
1442
1443 break;
1444 }
1445
1446 if(Tok.is(MMToken::Star)) {
1447 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001448 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001449 break;
1450 }
1451
1452 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1453 HadError = true;
1454 return;
1455 } while (true);
1456
1457 Module::UnresolvedExportDecl Unresolved = {
1458 ExportLoc, ParsedModuleId, Wildcard
1459 };
1460 ActiveModule->UnresolvedExports.push_back(Unresolved);
1461}
1462
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001463/// \brief Parse a link declaration.
1464///
1465/// module-declaration:
1466/// 'link' 'framework'[opt] string-literal
1467void ModuleMapParser::parseLinkDecl() {
1468 assert(Tok.is(MMToken::LinkKeyword));
1469 SourceLocation LinkLoc = consumeToken();
1470
1471 // Parse the optional 'framework' keyword.
1472 bool IsFramework = false;
1473 if (Tok.is(MMToken::FrameworkKeyword)) {
1474 consumeToken();
1475 IsFramework = true;
1476 }
1477
1478 // Parse the library name
1479 if (!Tok.is(MMToken::StringLiteral)) {
1480 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1481 << IsFramework << SourceRange(LinkLoc);
1482 HadError = true;
1483 return;
1484 }
1485
1486 std::string LibraryName = Tok.getString();
1487 consumeToken();
1488 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1489 IsFramework));
1490}
1491
1492/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001493///
1494/// module-declaration:
1495/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1496/// { inferred-module-member* }
1497///
1498/// inferred-module-member:
1499/// 'export' '*'
1500/// 'exclude' identifier
1501void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001502 assert(Tok.is(MMToken::Star));
1503 SourceLocation StarLoc = consumeToken();
1504 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001505
Douglas Gregor1e123682011-12-05 22:27:44 +00001506 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001507 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001508 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1509 Failed = true;
1510 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001511
1512 if (ActiveModule) {
1513 // Inferred modules must have umbrella directories.
1514 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1515 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1516 Failed = true;
1517 }
1518
1519 // Check for redefinition of an inferred module.
1520 if (!Failed && ActiveModule->InferSubmodules) {
1521 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1522 if (ActiveModule->InferredSubmoduleLoc.isValid())
1523 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1524 diag::note_mmap_prev_definition);
1525 Failed = true;
1526 }
1527
1528 // Check for the 'framework' keyword, which is not permitted here.
1529 if (Framework) {
1530 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1531 Framework = false;
1532 }
1533 } else if (Explicit) {
1534 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1535 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001536 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001537
Douglas Gregor1e123682011-12-05 22:27:44 +00001538 // If there were any problems with this inferred submodule, skip its body.
1539 if (Failed) {
1540 if (Tok.is(MMToken::LBrace)) {
1541 consumeToken();
1542 skipUntil(MMToken::RBrace);
1543 if (Tok.is(MMToken::RBrace))
1544 consumeToken();
1545 }
1546 HadError = true;
1547 return;
1548 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001549
1550 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001551 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001552 parseOptionalAttributes(Attrs);
1553
1554 if (ActiveModule) {
1555 // Note that we have an inferred submodule.
1556 ActiveModule->InferSubmodules = true;
1557 ActiveModule->InferredSubmoduleLoc = StarLoc;
1558 ActiveModule->InferExplicitSubmodules = Explicit;
1559 } else {
1560 // We'll be inferring framework modules for this directory.
1561 Map.InferredDirectories[Directory].InferModules = true;
1562 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1563 }
1564
Douglas Gregor1e123682011-12-05 22:27:44 +00001565 // Parse the opening brace.
1566 if (!Tok.is(MMToken::LBrace)) {
1567 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1568 HadError = true;
1569 return;
1570 }
1571 SourceLocation LBraceLoc = consumeToken();
1572
1573 // Parse the body of the inferred submodule.
1574 bool Done = false;
1575 do {
1576 switch (Tok.Kind) {
1577 case MMToken::EndOfFile:
1578 case MMToken::RBrace:
1579 Done = true;
1580 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001581
1582 case MMToken::ExcludeKeyword: {
1583 if (ActiveModule) {
1584 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001585 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001586 consumeToken();
1587 break;
1588 }
1589
1590 consumeToken();
1591 if (!Tok.is(MMToken::Identifier)) {
1592 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1593 break;
1594 }
1595
1596 Map.InferredDirectories[Directory].ExcludedModules
1597 .push_back(Tok.getString());
1598 consumeToken();
1599 break;
1600 }
1601
1602 case MMToken::ExportKeyword:
1603 if (!ActiveModule) {
1604 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001605 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001606 consumeToken();
1607 break;
1608 }
1609
Douglas Gregor1e123682011-12-05 22:27:44 +00001610 consumeToken();
1611 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001612 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001613 else
1614 Diags.Report(Tok.getLocation(),
1615 diag::err_mmap_expected_export_wildcard);
1616 consumeToken();
1617 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001618
Douglas Gregor1e123682011-12-05 22:27:44 +00001619 case MMToken::ExplicitKeyword:
1620 case MMToken::ModuleKeyword:
1621 case MMToken::HeaderKeyword:
1622 case MMToken::UmbrellaKeyword:
1623 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001624 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001625 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001626 consumeToken();
1627 break;
1628 }
1629 } while (!Done);
1630
1631 if (Tok.is(MMToken::RBrace))
1632 consumeToken();
1633 else {
1634 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1635 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1636 HadError = true;
1637 }
1638}
1639
Douglas Gregor82e52372012-11-06 19:39:40 +00001640/// \brief Parse optional attributes.
1641///
1642/// attributes:
1643/// attribute attributes
1644/// attribute
1645///
1646/// attribute:
1647/// [ identifier ]
1648///
1649/// \param Attrs Will be filled in with the parsed attributes.
1650///
1651/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001652bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001653 bool HadError = false;
1654
1655 while (Tok.is(MMToken::LSquare)) {
1656 // Consume the '['.
1657 SourceLocation LSquareLoc = consumeToken();
1658
1659 // Check whether we have an attribute name here.
1660 if (!Tok.is(MMToken::Identifier)) {
1661 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1662 skipUntil(MMToken::RSquare);
1663 if (Tok.is(MMToken::RSquare))
1664 consumeToken();
1665 HadError = true;
1666 }
1667
1668 // Decode the attribute name.
1669 AttributeKind Attribute
1670 = llvm::StringSwitch<AttributeKind>(Tok.getString())
1671 .Case("system", AT_system)
1672 .Default(AT_unknown);
1673 switch (Attribute) {
1674 case AT_unknown:
1675 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1676 << Tok.getString();
1677 break;
1678
1679 case AT_system:
1680 Attrs.IsSystem = true;
1681 break;
1682 }
1683 consumeToken();
1684
1685 // Consume the ']'.
1686 if (!Tok.is(MMToken::RSquare)) {
1687 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1688 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1689 skipUntil(MMToken::RSquare);
1690 HadError = true;
1691 }
1692
1693 if (Tok.is(MMToken::RSquare))
1694 consumeToken();
1695 }
1696
1697 return HadError;
1698}
1699
Douglas Gregor6a1db482011-12-09 02:04:43 +00001700/// \brief If there is a specific header search directory due the presence
1701/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1702const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1703 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1704 // If we have an umbrella directory, use that.
1705 if (Mod->hasUmbrellaDir())
1706 return Mod->getUmbrellaDir();
1707
1708 // If we have a framework directory, stop looking.
1709 if (Mod->IsFramework)
1710 return 0;
1711 }
1712
1713 return 0;
1714}
1715
Douglas Gregora30cfe52011-11-11 19:10:28 +00001716/// \brief Parse a module map file.
1717///
1718/// module-map-file:
1719/// module-declaration*
1720bool ModuleMapParser::parseModuleMapFile() {
1721 do {
1722 switch (Tok.Kind) {
1723 case MMToken::EndOfFile:
1724 return HadError;
1725
Douglas Gregor587986e2011-12-07 02:23:45 +00001726 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001727 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001728 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001729 parseModuleDecl();
1730 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001731
Douglas Gregor51f564f2011-12-31 04:05:44 +00001732 case MMToken::Comma:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001733 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001734 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001735 case MMToken::HeaderKeyword:
1736 case MMToken::Identifier:
1737 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001738 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001739 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001740 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001741 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001742 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001743 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001744 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001745 case MMToken::StringLiteral:
1746 case MMToken::UmbrellaKeyword:
1747 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1748 HadError = true;
1749 consumeToken();
1750 break;
1751 }
1752 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001753}
1754
1755bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001756 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1757 = ParsedModuleMap.find(File);
1758 if (Known != ParsedModuleMap.end())
1759 return Known->second;
1760
Douglas Gregordc58aa72012-01-30 06:01:29 +00001761 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001762 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1763 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1764 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001765 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001766
1767 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001768 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1769 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001770 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001771 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001772 bool Result = Parser.parseModuleMapFile();
1773 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001774 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001775 return Result;
1776}