blob: f9b4e2c9474c55f2113f8a18e93dae627305636d [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"
Chandler Carruth55fc8732012-12-04 09:13:33 +000021#include "clang/Lex/LexDiagnostic.h"
22#include "clang/Lex/Lexer.h"
23#include "clang/Lex/LiteralSupport.h"
24#include "llvm/ADT/StringRef.h"
25#include "llvm/ADT/StringSwitch.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000026#include "llvm/Support/Allocator.h"
Douglas Gregorac252a32011-12-06 19:39:29 +000027#include "llvm/Support/FileSystem.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000028#include "llvm/Support/Host.h"
Douglas Gregor8b6d3de2011-11-11 21:55:48 +000029#include "llvm/Support/PathV2.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000030#include "llvm/Support/raw_ostream.h"
Douglas Gregor98cfcbf2012-09-27 14:50:15 +000031#include <stdlib.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000032#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoadeb7822013-01-26 16:29:36 +000033#include <limits.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000034#endif
Douglas Gregora30cfe52011-11-11 19:10:28 +000035using namespace clang;
36
Douglas Gregor90db2602011-12-02 01:47:07 +000037Module::ExportDecl
38ModuleMap::resolveExport(Module *Mod,
39 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +000040 bool Complain) const {
Douglas Gregor0adaa882011-12-05 17:28:06 +000041 // We may have just a wildcard.
42 if (Unresolved.Id.empty()) {
43 assert(Unresolved.Wildcard && "Invalid unresolved export");
44 return Module::ExportDecl(0, true);
45 }
46
Douglas Gregor90db2602011-12-02 01:47:07 +000047 // Find the starting module.
48 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
49 if (!Context) {
50 if (Complain)
51 Diags->Report(Unresolved.Id[0].second,
52 diag::err_mmap_missing_module_unqualified)
53 << Unresolved.Id[0].first << Mod->getFullModuleName();
54
55 return Module::ExportDecl();
56 }
57
58 // Dig into the module path.
59 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
60 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
61 Context);
62 if (!Sub) {
63 if (Complain)
64 Diags->Report(Unresolved.Id[I].second,
65 diag::err_mmap_missing_module_qualified)
66 << Unresolved.Id[I].first << Context->getFullModuleName()
67 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
68
69 return Module::ExportDecl();
70 }
71
72 Context = Sub;
73 }
74
75 return Module::ExportDecl(Context, Unresolved.Wildcard);
76}
77
Douglas Gregor51f564f2011-12-31 04:05:44 +000078ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
Douglas Gregordc58aa72012-01-30 06:01:29 +000079 const LangOptions &LangOpts, const TargetInfo *Target)
Douglas Gregor2f04f182012-02-02 18:42:48 +000080 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000081{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000082 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
83 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000084 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora30cfe52011-11-11 19:10:28 +000085 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
86 SourceMgr = new SourceManager(*Diags, FileMgr);
87}
88
89ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +000090 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
91 IEnd = Modules.end();
92 I != IEnd; ++I) {
93 delete I->getValue();
94 }
95
Douglas Gregora30cfe52011-11-11 19:10:28 +000096 delete SourceMgr;
97}
98
Douglas Gregordc58aa72012-01-30 06:01:29 +000099void ModuleMap::setTarget(const TargetInfo &Target) {
100 assert((!this->Target || this->Target == &Target) &&
101 "Improper target override");
102 this->Target = &Target;
103}
104
Douglas Gregor8b48e082012-10-12 21:15:50 +0000105/// \brief "Sanitize" a filename so that it can be used as an identifier.
106static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
107 SmallVectorImpl<char> &Buffer) {
108 if (Name.empty())
109 return Name;
110
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000111 if (!isValidIdentifier(Name)) {
Douglas Gregor8b48e082012-10-12 21:15:50 +0000112 // If we don't already have something with the form of an identifier,
113 // create a buffer with the sanitized name.
114 Buffer.clear();
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000115 if (isDigit(Name[0]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000116 Buffer.push_back('_');
117 Buffer.reserve(Buffer.size() + Name.size());
118 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000119 if (isIdentifierBody(Name[I]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000120 Buffer.push_back(Name[I]);
121 else
122 Buffer.push_back('_');
123 }
124
125 Name = StringRef(Buffer.data(), Buffer.size());
126 }
127
128 while (llvm::StringSwitch<bool>(Name)
129#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
130#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
131#include "clang/Basic/TokenKinds.def"
132 .Default(false)) {
133 if (Name.data() != Buffer.data())
134 Buffer.append(Name.begin(), Name.end());
135 Buffer.push_back('_');
136 Name = StringRef(Buffer.data(), Buffer.size());
137 }
138
139 return Name;
140}
141
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000142Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000143 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000144 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000145 // If a header is not available, don't report that it maps to anything.
146 if (!Known->second.isAvailable())
Douglas Gregor51f564f2011-12-31 04:05:44 +0000147 return 0;
148
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000149 return Known->second.getModule();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000150 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000151
Douglas Gregoradb97992011-11-16 23:02:25 +0000152 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000153 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000154
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000155 // Note: as an egregious but useful hack we use the real path here, because
156 // frameworks moving from top-level frameworks to embedded frameworks tend
157 // to be symlinked from the top-level location to the embedded location,
158 // and we need to resolve lookups as if we had found the embedded location.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000159 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000160
161 // Keep walking up the directory hierarchy, looking for a directory with
162 // an umbrella header.
163 do {
164 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
165 = UmbrellaDirs.find(Dir);
166 if (KnownDir != UmbrellaDirs.end()) {
167 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000168
169 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000170 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000171 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000172 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000173 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000174
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000175 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000176 // Infer submodules for each of the directories we found between
177 // the directory of the umbrella header and the directory where
178 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000179 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000180
Douglas Gregor6a1db482011-12-09 02:04:43 +0000181 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000182 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000183 SmallString<32> NameBuf;
184 StringRef Name = sanitizeFilenameAsIdentifier(
185 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
186 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000187 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000188 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000189
190 // Associate the module and the directory.
191 UmbrellaDirs[SkippedDirs[I-1]] = Result;
192
193 // If inferred submodules export everything they import, add a
194 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000195 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000196 Result->Exports.push_back(Module::ExportDecl(0, true));
197 }
198
199 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000200 SmallString<32> NameBuf;
201 StringRef Name = sanitizeFilenameAsIdentifier(
202 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000203 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000204 Explicit).first;
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +0000205 Result->addTopHeader(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000206
207 // If inferred submodules export everything they import, add a
208 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000209 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000210 Result->Exports.push_back(Module::ExportDecl(0, true));
211 } else {
212 // Record each of the directories we stepped through as being part of
213 // the module we found, since the umbrella header covers them all.
214 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
215 UmbrellaDirs[SkippedDirs[I]] = Result;
216 }
217
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000218 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000219
220 // If a header corresponds to an unavailable module, don't report
221 // that it maps to anything.
222 if (!Result->isAvailable())
223 return 0;
224
Douglas Gregore209e502011-12-06 01:10:29 +0000225 return Result;
226 }
227
228 SkippedDirs.push_back(Dir);
229
Douglas Gregoradb97992011-11-16 23:02:25 +0000230 // Retrieve our parent path.
231 DirName = llvm::sys::path::parent_path(DirName);
232 if (DirName.empty())
233 break;
234
235 // Resolve the parent path to a directory entry.
236 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000237 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000238
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000239 return 0;
240}
241
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000242bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
243 HeadersMap::const_iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000244 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000245 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000246
247 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000248 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000249 StringRef DirName = Dir->getName();
250
251 // Keep walking up the directory hierarchy, looking for a directory with
252 // an umbrella header.
253 do {
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000254 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor51f564f2011-12-31 04:05:44 +0000255 = UmbrellaDirs.find(Dir);
256 if (KnownDir != UmbrellaDirs.end()) {
257 Module *Found = KnownDir->second;
258 if (!Found->isAvailable())
259 return true;
260
261 // Search up the module stack until we find a module with an umbrella
262 // directory.
263 Module *UmbrellaModule = Found;
264 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
265 UmbrellaModule = UmbrellaModule->Parent;
266
267 if (UmbrellaModule->InferSubmodules) {
268 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
269 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000270 SmallString<32> NameBuf;
271 StringRef Name = sanitizeFilenameAsIdentifier(
272 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
273 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000274 Found = lookupModuleQualified(Name, Found);
275 if (!Found)
276 return false;
277 if (!Found->isAvailable())
278 return true;
279 }
280
281 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000282 SmallString<32> NameBuf;
283 StringRef Name = sanitizeFilenameAsIdentifier(
284 llvm::sys::path::stem(Header->getName()),
285 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000286 Found = lookupModuleQualified(Name, Found);
287 if (!Found)
288 return false;
289 }
290
291 return !Found->isAvailable();
292 }
293
294 SkippedDirs.push_back(Dir);
295
296 // 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.
302 Dir = SourceMgr->getFileManager().getDirectory(DirName);
303 } while (Dir);
304
305 return false;
306}
307
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000308Module *ModuleMap::findModule(StringRef Name) const {
309 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor484535e2011-11-11 23:20:24 +0000310 if (Known != Modules.end())
311 return Known->getValue();
312
313 return 0;
314}
315
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000316Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
317 Module *Context) const {
Douglas Gregor90db2602011-12-02 01:47:07 +0000318 for(; Context; Context = Context->Parent) {
319 if (Module *Sub = lookupModuleQualified(Name, Context))
320 return Sub;
321 }
322
323 return findModule(Name);
324}
325
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000326Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor90db2602011-12-02 01:47:07 +0000327 if (!Context)
328 return findModule(Name);
329
Douglas Gregorb7a78192012-01-04 23:32:19 +0000330 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000331}
332
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000333std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000334ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
335 bool IsExplicit) {
336 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000337 if (Module *Sub = lookupModuleQualified(Name, Parent))
338 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000339
340 // Create a new module with this name.
341 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
342 IsExplicit);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000343 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000344 Modules[Name] = Result;
345 return std::make_pair(Result, true);
346}
347
Douglas Gregor82e52372012-11-06 19:39:40 +0000348bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000349 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000350 // Check whether we have already looked into the parent directory
351 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000352 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000353 inferred = InferredDirectories.find(ParentDir);
354 if (inferred == InferredDirectories.end())
355 return false;
356
357 if (!inferred->second.InferModules)
358 return false;
359
360 // We're allowed to infer for this directory, but make sure it's okay
361 // to infer this particular module.
362 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
363 inferred->second.ExcludedModules.end(),
364 Name) == inferred->second.ExcludedModules.end();
365
366 if (canInfer && inferred->second.InferSystemModules)
367 IsSystem = true;
368
369 return canInfer;
370}
371
Douglas Gregor8767dc22013-01-14 17:57:51 +0000372/// \brief For a framework module, infer the framework against which we
373/// should link.
374static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
375 FileManager &FileMgr) {
376 assert(Mod->IsFramework && "Can only infer linking for framework modules");
377 assert(!Mod->isSubFramework() &&
378 "Can only infer linking for top-level frameworks");
379
380 SmallString<128> LibName;
381 LibName += FrameworkDir->getName();
382 llvm::sys::path::append(LibName, Mod->Name);
383 if (FileMgr.getFile(LibName)) {
384 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
385 /*IsFramework=*/true));
386 }
387}
388
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000389Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000390ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000391 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000392 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000393 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000394 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000395 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
396 return Mod;
397
398 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000399
400 // If the framework has a parent path from which we're allowed to infer
401 // a framework module, do so.
402 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000403 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000404
Douglas Gregor7005b902013-01-10 01:43:00 +0000405 // Note: as an egregious but useful hack we use the real path here, because
406 // we might be looking at an embedded framework that symlinks out to a
407 // top-level framework, and we need to infer as if we were naming the
408 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000409 StringRef FrameworkDirName
410 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000411
Douglas Gregor82e52372012-11-06 19:39:40 +0000412 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000413 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000414 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000415 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000416 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
417 // Check whether we have already looked into the parent directory
418 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000419 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000420 inferred = InferredDirectories.find(ParentDir);
421 if (inferred == InferredDirectories.end()) {
422 // We haven't looked here before. Load a module map, if there is
423 // one.
424 SmallString<128> ModMapPath = Parent;
425 llvm::sys::path::append(ModMapPath, "module.map");
426 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
427 parseModuleMapFile(ModMapFile);
428 inferred = InferredDirectories.find(ParentDir);
429 }
430
431 if (inferred == InferredDirectories.end())
432 inferred = InferredDirectories.insert(
433 std::make_pair(ParentDir, InferredDirectory())).first;
434 }
435
436 if (inferred->second.InferModules) {
437 // We're allowed to infer for this directory, but make sure it's okay
438 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000439 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000440 canInfer = std::find(inferred->second.ExcludedModules.begin(),
441 inferred->second.ExcludedModules.end(),
442 Name) == inferred->second.ExcludedModules.end();
443
444 if (inferred->second.InferSystemModules)
445 IsSystem = true;
446 }
447 }
448 }
449
450 // If we're not allowed to infer a framework module, don't.
451 if (!canInfer)
452 return 0;
453 }
454
455
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000456 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000457 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000458 llvm::sys::path::append(UmbrellaName, "Headers");
459 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000460 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000461
462 // FIXME: If there's no umbrella header, we could probably scan the
463 // framework to load *everything*. But, it's not clear that this is a good
464 // idea.
465 if (!UmbrellaHeader)
466 return 0;
467
Douglas Gregorac252a32011-12-06 19:39:29 +0000468 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
469 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000470 if (IsSystem)
471 Result->IsSystem = IsSystem;
472
Douglas Gregorb7a78192012-01-04 23:32:19 +0000473 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000474 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000475
Douglas Gregor489ad432011-12-08 18:00:48 +0000476 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000477 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000478 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000479 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000480
481 // export *
482 Result->Exports.push_back(Module::ExportDecl(0, true));
483
Douglas Gregore209e502011-12-06 01:10:29 +0000484 // module * { export * }
485 Result->InferSubmodules = true;
486 Result->InferExportWildcard = true;
487
Douglas Gregorac252a32011-12-06 19:39:29 +0000488 // Look for subframeworks.
489 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000490 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000491 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000492 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000493 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000494 llvm::sys::path::native(SubframeworksDirName.str(),
495 SubframeworksDirNameNative);
496 for (llvm::sys::fs::directory_iterator
497 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000498 Dir != DirEnd && !EC; Dir.increment(EC)) {
499 if (!StringRef(Dir->path()).endswith(".framework"))
500 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000501
Douglas Gregorac252a32011-12-06 19:39:29 +0000502 if (const DirectoryEntry *SubframeworkDir
503 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000504 // Note: as an egregious but useful hack, we use the real path here and
505 // check whether it is actually a subdirectory of the parent directory.
506 // This will not be the case if the 'subframework' is actually a symlink
507 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000508 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
509 bool FoundParent = false;
510 do {
511 // Get the parent directory name.
512 SubframeworkDirName
513 = llvm::sys::path::parent_path(SubframeworkDirName);
514 if (SubframeworkDirName.empty())
515 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000516
Douglas Gregor713b7c02013-01-26 00:55:12 +0000517 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
518 FoundParent = true;
519 break;
520 }
521 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000522
Douglas Gregor713b7c02013-01-26 00:55:12 +0000523 if (!FoundParent)
524 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000525
Douglas Gregorac252a32011-12-06 19:39:29 +0000526 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000527 SmallString<32> NameBuf;
528 inferFrameworkModule(sanitizeFilenameAsIdentifier(
529 llvm::sys::path::stem(Dir->path()), NameBuf),
530 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000531 }
532 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000533
Douglas Gregor8767dc22013-01-14 17:57:51 +0000534 // If the module is a top-level framework, automatically link against the
535 // framework.
536 if (!Result->isSubFramework()) {
537 inferFrameworkLink(Result, FrameworkDir, FileMgr);
538 }
539
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000540 return Result;
541}
542
Douglas Gregore209e502011-12-06 01:10:29 +0000543void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000544 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000545 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000546 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000547}
548
Douglas Gregor77d029f2011-12-08 19:11:24 +0000549void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
550 Mod->Umbrella = UmbrellaDir;
551 UmbrellaDirs[UmbrellaDir] = Mod;
552}
553
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000554void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
555 bool Excluded) {
556 if (Excluded)
557 Mod->ExcludedHeaders.push_back(Header);
558 else
559 Mod->Headers.push_back(Header);
560 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000561}
562
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000563const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000564ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000565 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
566 return 0;
567
568 return SourceMgr->getFileEntryForID(
569 SourceMgr->getFileID(Module->DefinitionLoc));
570}
571
Douglas Gregora30cfe52011-11-11 19:10:28 +0000572void ModuleMap::dump() {
573 llvm::errs() << "Modules:";
574 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
575 MEnd = Modules.end();
576 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000577 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000578
579 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000580 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000581 H != HEnd; ++H) {
582 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000583 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000584 }
585}
586
Douglas Gregor90db2602011-12-02 01:47:07 +0000587bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
588 bool HadError = false;
589 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
590 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
591 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000592 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000593 Mod->Exports.push_back(Export);
594 else
595 HadError = true;
596 }
597 Mod->UnresolvedExports.clear();
598 return HadError;
599}
600
Douglas Gregor55988682011-12-05 16:33:54 +0000601Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
602 if (Loc.isInvalid())
603 return 0;
604
605 // Use the expansion location to determine which module we're in.
606 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
607 if (!ExpansionLoc.isFileID())
608 return 0;
609
610
611 const SourceManager &SrcMgr = Loc.getManager();
612 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000613
Douglas Gregor303aae92012-01-06 17:19:32 +0000614 while (const FileEntry *ExpansionFile
615 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
616 // Find the module that owns this header (if any).
617 if (Module *Mod = findModuleForHeader(ExpansionFile))
618 return Mod;
619
620 // No module owns this header, so look up the inclusion chain to see if
621 // any included header has an associated module.
622 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
623 if (IncludeLoc.isInvalid())
624 return 0;
625
626 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
627 }
628
629 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000630}
631
Douglas Gregora30cfe52011-11-11 19:10:28 +0000632//----------------------------------------------------------------------------//
633// Module map file parser
634//----------------------------------------------------------------------------//
635
636namespace clang {
637 /// \brief A token in a module map file.
638 struct MMToken {
639 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000640 Comma,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000641 EndOfFile,
642 HeaderKeyword,
643 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000644 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000645 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000646 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000647 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000648 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000649 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000650 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000651 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000652 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000653 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000654 StringLiteral,
655 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000656 RBrace,
657 LSquare,
658 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000659 } Kind;
660
661 unsigned Location;
662 unsigned StringLength;
663 const char *StringData;
664
665 void clear() {
666 Kind = EndOfFile;
667 Location = 0;
668 StringLength = 0;
669 StringData = 0;
670 }
671
672 bool is(TokenKind K) const { return Kind == K; }
673
674 SourceLocation getLocation() const {
675 return SourceLocation::getFromRawEncoding(Location);
676 }
677
678 StringRef getString() const {
679 return StringRef(StringData, StringLength);
680 }
681 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000682
683 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000684 struct Attributes {
685 Attributes() : IsSystem() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000686
687 /// \brief Whether this is a system module.
688 unsigned IsSystem : 1;
689 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000690
Douglas Gregor82e52372012-11-06 19:39:40 +0000691
Douglas Gregora30cfe52011-11-11 19:10:28 +0000692 class ModuleMapParser {
693 Lexer &L;
694 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000695
696 /// \brief Default target information, used only for string literal
697 /// parsing.
698 const TargetInfo *Target;
699
Douglas Gregora30cfe52011-11-11 19:10:28 +0000700 DiagnosticsEngine &Diags;
701 ModuleMap &Map;
702
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000703 /// \brief The directory that this module map resides in.
704 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000705
706 /// \brief The directory containing Clang-supplied headers.
707 const DirectoryEntry *BuiltinIncludeDir;
708
Douglas Gregora30cfe52011-11-11 19:10:28 +0000709 /// \brief Whether an error occurred.
710 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000711
Douglas Gregora30cfe52011-11-11 19:10:28 +0000712 /// \brief Stores string data for the various string literals referenced
713 /// during parsing.
714 llvm::BumpPtrAllocator StringData;
715
716 /// \brief The current token.
717 MMToken Tok;
718
719 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000720 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000721
722 /// \brief Consume the current token and return its location.
723 SourceLocation consumeToken();
724
725 /// \brief Skip tokens until we reach the a token with the given kind
726 /// (or the end of the file).
727 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000728
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000729 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000730 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000731 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000732 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000733 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000734 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000735 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000736 void parseLinkDecl();
Douglas Gregor82e52372012-11-06 19:39:40 +0000737 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000738 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000739
Douglas Gregor6a1db482011-12-09 02:04:43 +0000740 const DirectoryEntry *getOverriddenHeaderSearchDir();
741
Douglas Gregora30cfe52011-11-11 19:10:28 +0000742 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000743 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000744 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000745 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000746 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000747 const DirectoryEntry *Directory,
748 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000749 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000750 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
751 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000752 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000753 Tok.clear();
754 consumeToken();
755 }
756
757 bool parseModuleMapFile();
758 };
759}
760
761SourceLocation ModuleMapParser::consumeToken() {
762retry:
763 SourceLocation Result = Tok.getLocation();
764 Tok.clear();
765
766 Token LToken;
767 L.LexFromRawLexer(LToken);
768 Tok.Location = LToken.getLocation().getRawEncoding();
769 switch (LToken.getKind()) {
770 case tok::raw_identifier:
771 Tok.StringData = LToken.getRawIdentifierData();
772 Tok.StringLength = LToken.getLength();
773 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
774 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000775 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000776 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000777 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000778 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000779 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000780 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000781 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000782 .Case("umbrella", MMToken::UmbrellaKeyword)
783 .Default(MMToken::Identifier);
784 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000785
786 case tok::comma:
787 Tok.Kind = MMToken::Comma;
788 break;
789
Douglas Gregora30cfe52011-11-11 19:10:28 +0000790 case tok::eof:
791 Tok.Kind = MMToken::EndOfFile;
792 break;
793
794 case tok::l_brace:
795 Tok.Kind = MMToken::LBrace;
796 break;
797
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000798 case tok::l_square:
799 Tok.Kind = MMToken::LSquare;
800 break;
801
Douglas Gregor90db2602011-12-02 01:47:07 +0000802 case tok::period:
803 Tok.Kind = MMToken::Period;
804 break;
805
Douglas Gregora30cfe52011-11-11 19:10:28 +0000806 case tok::r_brace:
807 Tok.Kind = MMToken::RBrace;
808 break;
809
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000810 case tok::r_square:
811 Tok.Kind = MMToken::RSquare;
812 break;
813
Douglas Gregor90db2602011-12-02 01:47:07 +0000814 case tok::star:
815 Tok.Kind = MMToken::Star;
816 break;
817
Douglas Gregora30cfe52011-11-11 19:10:28 +0000818 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000819 if (LToken.hasUDSuffix()) {
820 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
821 HadError = true;
822 goto retry;
823 }
824
Douglas Gregora30cfe52011-11-11 19:10:28 +0000825 // Parse the string literal.
826 LangOptions LangOpts;
827 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
828 if (StringLiteral.hadError)
829 goto retry;
830
831 // Copy the string literal into our string data allocator.
832 unsigned Length = StringLiteral.GetStringLength();
833 char *Saved = StringData.Allocate<char>(Length + 1);
834 memcpy(Saved, StringLiteral.GetString().data(), Length);
835 Saved[Length] = 0;
836
837 // Form the token.
838 Tok.Kind = MMToken::StringLiteral;
839 Tok.StringData = Saved;
840 Tok.StringLength = Length;
841 break;
842 }
843
844 case tok::comment:
845 goto retry;
846
847 default:
848 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
849 HadError = true;
850 goto retry;
851 }
852
853 return Result;
854}
855
856void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
857 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000858 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000859 do {
860 switch (Tok.Kind) {
861 case MMToken::EndOfFile:
862 return;
863
864 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000865 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000866 return;
867
868 ++braceDepth;
869 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000870
871 case MMToken::LSquare:
872 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
873 return;
874
875 ++squareDepth;
876 break;
877
Douglas Gregora30cfe52011-11-11 19:10:28 +0000878 case MMToken::RBrace:
879 if (braceDepth > 0)
880 --braceDepth;
881 else if (Tok.is(K))
882 return;
883 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000884
885 case MMToken::RSquare:
886 if (squareDepth > 0)
887 --squareDepth;
888 else if (Tok.is(K))
889 return;
890 break;
891
Douglas Gregora30cfe52011-11-11 19:10:28 +0000892 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000893 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000894 return;
895 break;
896 }
897
898 consumeToken();
899 } while (true);
900}
901
Douglas Gregor587986e2011-12-07 02:23:45 +0000902/// \brief Parse a module-id.
903///
904/// module-id:
905/// identifier
906/// identifier '.' module-id
907///
908/// \returns true if an error occurred, false otherwise.
909bool ModuleMapParser::parseModuleId(ModuleId &Id) {
910 Id.clear();
911 do {
912 if (Tok.is(MMToken::Identifier)) {
913 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
914 consumeToken();
915 } else {
916 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
917 return true;
918 }
919
920 if (!Tok.is(MMToken::Period))
921 break;
922
923 consumeToken();
924 } while (true);
925
926 return false;
927}
928
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000929namespace {
930 /// \brief Enumerates the known attributes.
931 enum AttributeKind {
932 /// \brief An unknown attribute.
933 AT_unknown,
934 /// \brief The 'system' attribute.
935 AT_system
936 };
937}
938
Douglas Gregora30cfe52011-11-11 19:10:28 +0000939/// \brief Parse a module declaration.
940///
941/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000942/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
943/// { module-member* }
944///
Douglas Gregora30cfe52011-11-11 19:10:28 +0000945/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +0000946/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000947/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +0000948/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +0000949/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000950/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +0000951///
952/// submodule-declaration:
953/// module-declaration
954/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000955void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +0000956 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
957 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +0000958 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +0000959 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000960 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +0000961 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +0000962
Douglas Gregord620a842011-12-06 17:16:41 +0000963 // Parse 'explicit' keyword, if present.
964 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +0000965 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +0000966 Explicit = true;
967 }
968
969 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +0000970 if (Tok.is(MMToken::FrameworkKeyword)) {
971 consumeToken();
972 Framework = true;
973 }
Douglas Gregora30cfe52011-11-11 19:10:28 +0000974
975 // Parse 'module' keyword.
976 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +0000977 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000978 consumeToken();
979 HadError = true;
980 return;
981 }
982 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +0000983
984 // If we have a wildcard for the module name, this is an inferred submodule.
985 // Parse it.
986 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +0000987 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000988
989 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +0000990 ModuleId Id;
991 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000992 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +0000993 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000994 }
Douglas Gregor82e52372012-11-06 19:39:40 +0000995
Douglas Gregor587986e2011-12-07 02:23:45 +0000996 if (ActiveModule) {
997 if (Id.size() > 1) {
998 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
999 << SourceRange(Id.front().second, Id.back().second);
1000
1001 HadError = true;
1002 return;
1003 }
1004 } else if (Id.size() == 1 && Explicit) {
1005 // Top-level modules can't be explicit.
1006 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1007 Explicit = false;
1008 ExplicitLoc = SourceLocation();
1009 HadError = true;
1010 }
1011
1012 Module *PreviousActiveModule = ActiveModule;
1013 if (Id.size() > 1) {
1014 // This module map defines a submodule. Go find the module of which it
1015 // is a submodule.
1016 ActiveModule = 0;
1017 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1018 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1019 ActiveModule = Next;
1020 continue;
1021 }
1022
1023 if (ActiveModule) {
1024 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1025 << Id[I].first << ActiveModule->getTopLevelModule();
1026 } else {
1027 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1028 }
1029 HadError = true;
1030 return;
1031 }
1032 }
1033
1034 StringRef ModuleName = Id.back().first;
1035 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001036
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001037 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001038 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001039 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001040
Douglas Gregora30cfe52011-11-11 19:10:28 +00001041 // Parse the opening brace.
1042 if (!Tok.is(MMToken::LBrace)) {
1043 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1044 << ModuleName;
1045 HadError = true;
1046 return;
1047 }
1048 SourceLocation LBraceLoc = consumeToken();
1049
1050 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001051 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001052 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1053 // Skip the module definition.
1054 skipUntil(MMToken::RBrace);
1055 if (Tok.is(MMToken::RBrace))
1056 consumeToken();
1057 else {
1058 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1059 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1060 HadError = true;
1061 }
1062 return;
1063 }
1064
Douglas Gregora30cfe52011-11-11 19:10:28 +00001065 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1066 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001067 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001068
1069 // Skip the module definition.
1070 skipUntil(MMToken::RBrace);
1071 if (Tok.is(MMToken::RBrace))
1072 consumeToken();
1073
1074 HadError = true;
1075 return;
1076 }
1077
1078 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001079 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1080 Explicit).first;
1081 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001082 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001083 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001084
1085 bool Done = false;
1086 do {
1087 switch (Tok.Kind) {
1088 case MMToken::EndOfFile:
1089 case MMToken::RBrace:
1090 Done = true;
1091 break;
1092
1093 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001094 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001095 case MMToken::ModuleKeyword:
1096 parseModuleDecl();
1097 break;
1098
Douglas Gregor90db2602011-12-02 01:47:07 +00001099 case MMToken::ExportKeyword:
1100 parseExportDecl();
1101 break;
1102
Douglas Gregor51f564f2011-12-31 04:05:44 +00001103 case MMToken::RequiresKeyword:
1104 parseRequiresDecl();
1105 break;
1106
Douglas Gregor77d029f2011-12-08 19:11:24 +00001107 case MMToken::UmbrellaKeyword: {
1108 SourceLocation UmbrellaLoc = consumeToken();
1109 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001110 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001111 else
1112 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001113 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001114 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001115
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001116 case MMToken::ExcludeKeyword: {
1117 SourceLocation ExcludeLoc = consumeToken();
1118 if (Tok.is(MMToken::HeaderKeyword)) {
1119 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1120 } else {
1121 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1122 << "exclude";
1123 }
1124 break;
1125 }
1126
Douglas Gregor489ad432011-12-08 18:00:48 +00001127 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001128 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001129 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001130
1131 case MMToken::LinkKeyword:
1132 parseLinkDecl();
1133 break;
1134
Douglas Gregora30cfe52011-11-11 19:10:28 +00001135 default:
1136 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1137 consumeToken();
1138 break;
1139 }
1140 } while (!Done);
1141
1142 if (Tok.is(MMToken::RBrace))
1143 consumeToken();
1144 else {
1145 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1146 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1147 HadError = true;
1148 }
1149
Douglas Gregor8767dc22013-01-14 17:57:51 +00001150 // If the active module is a top-level framework, and there are no link
1151 // libraries, automatically link against the framework.
1152 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1153 ActiveModule->LinkLibraries.empty()) {
1154 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1155 }
1156
Douglas Gregor587986e2011-12-07 02:23:45 +00001157 // We're done parsing this module. Pop back to the previous module.
1158 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001159}
Douglas Gregord620a842011-12-06 17:16:41 +00001160
Douglas Gregor51f564f2011-12-31 04:05:44 +00001161/// \brief Parse a requires declaration.
1162///
1163/// requires-declaration:
1164/// 'requires' feature-list
1165///
1166/// feature-list:
1167/// identifier ',' feature-list
1168/// identifier
1169void ModuleMapParser::parseRequiresDecl() {
1170 assert(Tok.is(MMToken::RequiresKeyword));
1171
1172 // Parse 'requires' keyword.
1173 consumeToken();
1174
1175 // Parse the feature-list.
1176 do {
1177 if (!Tok.is(MMToken::Identifier)) {
1178 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1179 HadError = true;
1180 return;
1181 }
1182
1183 // Consume the feature name.
1184 std::string Feature = Tok.getString();
1185 consumeToken();
1186
1187 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001188 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001189
1190 if (!Tok.is(MMToken::Comma))
1191 break;
1192
1193 // Consume the comma.
1194 consumeToken();
1195 } while (true);
1196}
1197
Douglas Gregord620a842011-12-06 17:16:41 +00001198/// \brief Append to \p Paths the set of paths needed to get to the
1199/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001200static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001201 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001202 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001203 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001204 for (; Mod; Mod = Mod->Parent) {
1205 if (Mod->IsFramework)
1206 Paths.push_back(Mod->Name);
1207 }
1208
1209 if (Paths.empty())
1210 return;
1211
1212 // Add Frameworks/Name.framework for each subframework.
1213 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1214 llvm::sys::path::append(Path, "Frameworks");
1215 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1216 }
1217}
1218
Douglas Gregor2f04f182012-02-02 18:42:48 +00001219/// \brief Determine whether the given file name is the name of a builtin
1220/// header, supplied by Clang to replace, override, or augment existing system
1221/// headers.
1222static bool isBuiltinHeader(StringRef FileName) {
1223 return llvm::StringSwitch<bool>(FileName)
1224 .Case("float.h", true)
1225 .Case("iso646.h", true)
1226 .Case("limits.h", true)
1227 .Case("stdalign.h", true)
1228 .Case("stdarg.h", true)
1229 .Case("stdbool.h", true)
1230 .Case("stddef.h", true)
1231 .Case("stdint.h", true)
1232 .Case("tgmath.h", true)
1233 .Case("unwind.h", true)
1234 .Default(false);
1235}
1236
Douglas Gregora30cfe52011-11-11 19:10:28 +00001237/// \brief Parse a header declaration.
1238///
1239/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001240/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001241/// 'exclude'[opt] 'header' string-literal
1242void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1243 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001244 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001245 consumeToken();
1246
Douglas Gregor489ad432011-12-08 18:00:48 +00001247 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001248 bool Exclude = ExcludeLoc.isValid();
1249 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001250 // Parse the header name.
1251 if (!Tok.is(MMToken::StringLiteral)) {
1252 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1253 << "header";
1254 HadError = true;
1255 return;
1256 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001257 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001258 SourceLocation FileNameLoc = consumeToken();
1259
Douglas Gregor77d029f2011-12-08 19:11:24 +00001260 // Check whether we already have an umbrella.
1261 if (Umbrella && ActiveModule->Umbrella) {
1262 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1263 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001264 HadError = true;
1265 return;
1266 }
1267
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001268 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001269 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001270 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001271 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001272 if (llvm::sys::path::is_absolute(FileName)) {
1273 PathName = FileName;
1274 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001275 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1276 PathName = Dir->getName();
1277 llvm::sys::path::append(PathName, FileName);
1278 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001279 } else {
1280 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001281 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001282 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001283
Douglas Gregord620a842011-12-06 17:16:41 +00001284 if (ActiveModule->isPartOfFramework()) {
1285 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001286
1287 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001288 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001289 llvm::sys::path::append(PathName, FileName);
1290 File = SourceMgr.getFileManager().getFile(PathName);
1291
1292 if (!File) {
1293 // Check whether this file is in the private headers.
1294 PathName.resize(PathLength);
1295 llvm::sys::path::append(PathName, "PrivateHeaders");
1296 llvm::sys::path::append(PathName, FileName);
1297 File = SourceMgr.getFileManager().getFile(PathName);
1298 }
1299 } else {
1300 // Lookup for normal headers.
1301 llvm::sys::path::append(PathName, FileName);
1302 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001303
1304 // If this is a system module with a top-level header, this header
1305 // may have a counterpart (or replacement) in the set of headers
1306 // supplied by Clang. Find that builtin header.
1307 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1308 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001309 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001310 llvm::sys::path::append(BuiltinPathName, FileName);
1311 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1312
1313 // If Clang supplies this header but the underlying system does not,
1314 // just silently swap in our builtin version. Otherwise, we'll end
1315 // up adding both (later).
1316 if (!File && BuiltinFile) {
1317 File = BuiltinFile;
1318 BuiltinFile = 0;
1319 }
1320 }
Douglas Gregord620a842011-12-06 17:16:41 +00001321 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001322 }
Douglas Gregora8654052011-11-17 22:09:43 +00001323
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001324 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1325 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001326 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001327 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001328 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001329 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001330 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001331 } else if (Umbrella) {
1332 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001333 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001334 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001335 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001336 HadError = true;
1337 } else {
1338 // Record this umbrella header.
1339 Map.setUmbrellaHeader(ActiveModule, File);
1340 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001341 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001342 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001343 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001344
1345 // If there is a builtin counterpart to this file, add it now.
1346 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001347 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001348 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001349 } else if (!Exclude) {
1350 // Ignore excluded header files. They're optional anyway.
1351
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001352 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001353 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001354 HadError = true;
1355 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001356}
1357
Douglas Gregor77d029f2011-12-08 19:11:24 +00001358/// \brief Parse an umbrella directory declaration.
1359///
1360/// umbrella-dir-declaration:
1361/// umbrella string-literal
1362void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1363 // Parse the directory name.
1364 if (!Tok.is(MMToken::StringLiteral)) {
1365 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1366 << "umbrella";
1367 HadError = true;
1368 return;
1369 }
1370
1371 std::string DirName = Tok.getString();
1372 SourceLocation DirNameLoc = consumeToken();
1373
1374 // Check whether we already have an umbrella.
1375 if (ActiveModule->Umbrella) {
1376 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1377 << ActiveModule->getFullModuleName();
1378 HadError = true;
1379 return;
1380 }
1381
1382 // Look for this file.
1383 const DirectoryEntry *Dir = 0;
1384 if (llvm::sys::path::is_absolute(DirName))
1385 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1386 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001387 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001388 PathName = Directory->getName();
1389 llvm::sys::path::append(PathName, DirName);
1390 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1391 }
1392
1393 if (!Dir) {
1394 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1395 << DirName;
1396 HadError = true;
1397 return;
1398 }
1399
1400 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1401 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1402 << OwningModule->getFullModuleName();
1403 HadError = true;
1404 return;
1405 }
1406
1407 // Record this umbrella directory.
1408 Map.setUmbrellaDir(ActiveModule, Dir);
1409}
1410
Douglas Gregor90db2602011-12-02 01:47:07 +00001411/// \brief Parse a module export declaration.
1412///
1413/// export-declaration:
1414/// 'export' wildcard-module-id
1415///
1416/// wildcard-module-id:
1417/// identifier
1418/// '*'
1419/// identifier '.' wildcard-module-id
1420void ModuleMapParser::parseExportDecl() {
1421 assert(Tok.is(MMToken::ExportKeyword));
1422 SourceLocation ExportLoc = consumeToken();
1423
1424 // Parse the module-id with an optional wildcard at the end.
1425 ModuleId ParsedModuleId;
1426 bool Wildcard = false;
1427 do {
1428 if (Tok.is(MMToken::Identifier)) {
1429 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1430 Tok.getLocation()));
1431 consumeToken();
1432
1433 if (Tok.is(MMToken::Period)) {
1434 consumeToken();
1435 continue;
1436 }
1437
1438 break;
1439 }
1440
1441 if(Tok.is(MMToken::Star)) {
1442 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001443 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001444 break;
1445 }
1446
1447 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1448 HadError = true;
1449 return;
1450 } while (true);
1451
1452 Module::UnresolvedExportDecl Unresolved = {
1453 ExportLoc, ParsedModuleId, Wildcard
1454 };
1455 ActiveModule->UnresolvedExports.push_back(Unresolved);
1456}
1457
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001458/// \brief Parse a link declaration.
1459///
1460/// module-declaration:
1461/// 'link' 'framework'[opt] string-literal
1462void ModuleMapParser::parseLinkDecl() {
1463 assert(Tok.is(MMToken::LinkKeyword));
1464 SourceLocation LinkLoc = consumeToken();
1465
1466 // Parse the optional 'framework' keyword.
1467 bool IsFramework = false;
1468 if (Tok.is(MMToken::FrameworkKeyword)) {
1469 consumeToken();
1470 IsFramework = true;
1471 }
1472
1473 // Parse the library name
1474 if (!Tok.is(MMToken::StringLiteral)) {
1475 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1476 << IsFramework << SourceRange(LinkLoc);
1477 HadError = true;
1478 return;
1479 }
1480
1481 std::string LibraryName = Tok.getString();
1482 consumeToken();
1483 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1484 IsFramework));
1485}
1486
1487/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001488///
1489/// module-declaration:
1490/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1491/// { inferred-module-member* }
1492///
1493/// inferred-module-member:
1494/// 'export' '*'
1495/// 'exclude' identifier
1496void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001497 assert(Tok.is(MMToken::Star));
1498 SourceLocation StarLoc = consumeToken();
1499 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001500
Douglas Gregor1e123682011-12-05 22:27:44 +00001501 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001502 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001503 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1504 Failed = true;
1505 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001506
1507 if (ActiveModule) {
1508 // Inferred modules must have umbrella directories.
1509 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1510 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1511 Failed = true;
1512 }
1513
1514 // Check for redefinition of an inferred module.
1515 if (!Failed && ActiveModule->InferSubmodules) {
1516 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1517 if (ActiveModule->InferredSubmoduleLoc.isValid())
1518 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1519 diag::note_mmap_prev_definition);
1520 Failed = true;
1521 }
1522
1523 // Check for the 'framework' keyword, which is not permitted here.
1524 if (Framework) {
1525 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1526 Framework = false;
1527 }
1528 } else if (Explicit) {
1529 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1530 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001531 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001532
Douglas Gregor1e123682011-12-05 22:27:44 +00001533 // If there were any problems with this inferred submodule, skip its body.
1534 if (Failed) {
1535 if (Tok.is(MMToken::LBrace)) {
1536 consumeToken();
1537 skipUntil(MMToken::RBrace);
1538 if (Tok.is(MMToken::RBrace))
1539 consumeToken();
1540 }
1541 HadError = true;
1542 return;
1543 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001544
1545 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001546 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001547 parseOptionalAttributes(Attrs);
1548
1549 if (ActiveModule) {
1550 // Note that we have an inferred submodule.
1551 ActiveModule->InferSubmodules = true;
1552 ActiveModule->InferredSubmoduleLoc = StarLoc;
1553 ActiveModule->InferExplicitSubmodules = Explicit;
1554 } else {
1555 // We'll be inferring framework modules for this directory.
1556 Map.InferredDirectories[Directory].InferModules = true;
1557 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1558 }
1559
Douglas Gregor1e123682011-12-05 22:27:44 +00001560 // Parse the opening brace.
1561 if (!Tok.is(MMToken::LBrace)) {
1562 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1563 HadError = true;
1564 return;
1565 }
1566 SourceLocation LBraceLoc = consumeToken();
1567
1568 // Parse the body of the inferred submodule.
1569 bool Done = false;
1570 do {
1571 switch (Tok.Kind) {
1572 case MMToken::EndOfFile:
1573 case MMToken::RBrace:
1574 Done = true;
1575 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001576
1577 case MMToken::ExcludeKeyword: {
1578 if (ActiveModule) {
1579 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001580 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001581 consumeToken();
1582 break;
1583 }
1584
1585 consumeToken();
1586 if (!Tok.is(MMToken::Identifier)) {
1587 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1588 break;
1589 }
1590
1591 Map.InferredDirectories[Directory].ExcludedModules
1592 .push_back(Tok.getString());
1593 consumeToken();
1594 break;
1595 }
1596
1597 case MMToken::ExportKeyword:
1598 if (!ActiveModule) {
1599 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001600 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001601 consumeToken();
1602 break;
1603 }
1604
Douglas Gregor1e123682011-12-05 22:27:44 +00001605 consumeToken();
1606 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001607 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001608 else
1609 Diags.Report(Tok.getLocation(),
1610 diag::err_mmap_expected_export_wildcard);
1611 consumeToken();
1612 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001613
Douglas Gregor1e123682011-12-05 22:27:44 +00001614 case MMToken::ExplicitKeyword:
1615 case MMToken::ModuleKeyword:
1616 case MMToken::HeaderKeyword:
1617 case MMToken::UmbrellaKeyword:
1618 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001619 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001620 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001621 consumeToken();
1622 break;
1623 }
1624 } while (!Done);
1625
1626 if (Tok.is(MMToken::RBrace))
1627 consumeToken();
1628 else {
1629 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1630 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1631 HadError = true;
1632 }
1633}
1634
Douglas Gregor82e52372012-11-06 19:39:40 +00001635/// \brief Parse optional attributes.
1636///
1637/// attributes:
1638/// attribute attributes
1639/// attribute
1640///
1641/// attribute:
1642/// [ identifier ]
1643///
1644/// \param Attrs Will be filled in with the parsed attributes.
1645///
1646/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001647bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001648 bool HadError = false;
1649
1650 while (Tok.is(MMToken::LSquare)) {
1651 // Consume the '['.
1652 SourceLocation LSquareLoc = consumeToken();
1653
1654 // Check whether we have an attribute name here.
1655 if (!Tok.is(MMToken::Identifier)) {
1656 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1657 skipUntil(MMToken::RSquare);
1658 if (Tok.is(MMToken::RSquare))
1659 consumeToken();
1660 HadError = true;
1661 }
1662
1663 // Decode the attribute name.
1664 AttributeKind Attribute
1665 = llvm::StringSwitch<AttributeKind>(Tok.getString())
1666 .Case("system", AT_system)
1667 .Default(AT_unknown);
1668 switch (Attribute) {
1669 case AT_unknown:
1670 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1671 << Tok.getString();
1672 break;
1673
1674 case AT_system:
1675 Attrs.IsSystem = true;
1676 break;
1677 }
1678 consumeToken();
1679
1680 // Consume the ']'.
1681 if (!Tok.is(MMToken::RSquare)) {
1682 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1683 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1684 skipUntil(MMToken::RSquare);
1685 HadError = true;
1686 }
1687
1688 if (Tok.is(MMToken::RSquare))
1689 consumeToken();
1690 }
1691
1692 return HadError;
1693}
1694
Douglas Gregor6a1db482011-12-09 02:04:43 +00001695/// \brief If there is a specific header search directory due the presence
1696/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1697const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1698 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1699 // If we have an umbrella directory, use that.
1700 if (Mod->hasUmbrellaDir())
1701 return Mod->getUmbrellaDir();
1702
1703 // If we have a framework directory, stop looking.
1704 if (Mod->IsFramework)
1705 return 0;
1706 }
1707
1708 return 0;
1709}
1710
Douglas Gregora30cfe52011-11-11 19:10:28 +00001711/// \brief Parse a module map file.
1712///
1713/// module-map-file:
1714/// module-declaration*
1715bool ModuleMapParser::parseModuleMapFile() {
1716 do {
1717 switch (Tok.Kind) {
1718 case MMToken::EndOfFile:
1719 return HadError;
1720
Douglas Gregor587986e2011-12-07 02:23:45 +00001721 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001722 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001723 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001724 parseModuleDecl();
1725 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001726
Douglas Gregor51f564f2011-12-31 04:05:44 +00001727 case MMToken::Comma:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001728 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001729 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001730 case MMToken::HeaderKeyword:
1731 case MMToken::Identifier:
1732 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001733 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001734 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001735 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001736 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001737 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001738 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001739 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001740 case MMToken::StringLiteral:
1741 case MMToken::UmbrellaKeyword:
1742 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1743 HadError = true;
1744 consumeToken();
1745 break;
1746 }
1747 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001748}
1749
1750bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001751 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1752 = ParsedModuleMap.find(File);
1753 if (Known != ParsedModuleMap.end())
1754 return Known->second;
1755
Douglas Gregordc58aa72012-01-30 06:01:29 +00001756 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001757 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1758 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1759 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001760 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001761
1762 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001763 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1764 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001765 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001766 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001767 bool Result = Parser.parseModuleMapFile();
1768 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001769 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001770 return Result;
1771}