blob: 0c03201aa6d42434213a69263a146b07e1d7ebcf [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 Gregor906d66a2013-03-20 21:10:35 +000048 // Resolve the module-id.
49 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
50 if (!Context)
51 return Module::ExportDecl();
52
53 return Module::ExportDecl(Context, Unresolved.Wildcard);
54}
55
56Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
57 bool Complain) const {
Douglas Gregor90db2602011-12-02 01:47:07 +000058 // Find the starting module.
Douglas Gregor906d66a2013-03-20 21:10:35 +000059 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor90db2602011-12-02 01:47:07 +000060 if (!Context) {
61 if (Complain)
Douglas Gregor906d66a2013-03-20 21:10:35 +000062 Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
63 << Id[0].first << Mod->getFullModuleName();
64
65 return 0;
Douglas Gregor90db2602011-12-02 01:47:07 +000066 }
67
68 // Dig into the module path.
Douglas Gregor906d66a2013-03-20 21:10:35 +000069 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
70 Module *Sub = lookupModuleQualified(Id[I].first, Context);
Douglas Gregor90db2602011-12-02 01:47:07 +000071 if (!Sub) {
72 if (Complain)
Douglas Gregor906d66a2013-03-20 21:10:35 +000073 Diags->Report(Id[I].second, diag::err_mmap_missing_module_qualified)
74 << Id[I].first << Context->getFullModuleName()
75 << SourceRange(Id[0].second, Id[I-1].second);
76
77 return 0;
Douglas Gregor90db2602011-12-02 01:47:07 +000078 }
Douglas Gregor906d66a2013-03-20 21:10:35 +000079
Douglas Gregor90db2602011-12-02 01:47:07 +000080 Context = Sub;
81 }
Douglas Gregor906d66a2013-03-20 21:10:35 +000082
83 return Context;
Douglas Gregor90db2602011-12-02 01:47:07 +000084}
85
Douglas Gregor51f564f2011-12-31 04:05:44 +000086ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000087 const LangOptions &LangOpts, const TargetInfo *Target,
88 HeaderSearch &HeaderInfo)
89 : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
90 BuiltinIncludeDir(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000091{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000092 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
93 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000094 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora30cfe52011-11-11 19:10:28 +000095 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
96 SourceMgr = new SourceManager(*Diags, FileMgr);
97}
98
99ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +0000100 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
101 IEnd = Modules.end();
102 I != IEnd; ++I) {
103 delete I->getValue();
104 }
105
Douglas Gregora30cfe52011-11-11 19:10:28 +0000106 delete SourceMgr;
107}
108
Douglas Gregordc58aa72012-01-30 06:01:29 +0000109void ModuleMap::setTarget(const TargetInfo &Target) {
110 assert((!this->Target || this->Target == &Target) &&
111 "Improper target override");
112 this->Target = &Target;
113}
114
Douglas Gregor8b48e082012-10-12 21:15:50 +0000115/// \brief "Sanitize" a filename so that it can be used as an identifier.
116static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
117 SmallVectorImpl<char> &Buffer) {
118 if (Name.empty())
119 return Name;
120
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000121 if (!isValidIdentifier(Name)) {
Douglas Gregor8b48e082012-10-12 21:15:50 +0000122 // If we don't already have something with the form of an identifier,
123 // create a buffer with the sanitized name.
124 Buffer.clear();
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000125 if (isDigit(Name[0]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000126 Buffer.push_back('_');
127 Buffer.reserve(Buffer.size() + Name.size());
128 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000129 if (isIdentifierBody(Name[I]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000130 Buffer.push_back(Name[I]);
131 else
132 Buffer.push_back('_');
133 }
134
135 Name = StringRef(Buffer.data(), Buffer.size());
136 }
137
138 while (llvm::StringSwitch<bool>(Name)
139#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
140#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
141#include "clang/Basic/TokenKinds.def"
142 .Default(false)) {
143 if (Name.data() != Buffer.data())
144 Buffer.append(Name.begin(), Name.end());
145 Buffer.push_back('_');
146 Name = StringRef(Buffer.data(), Buffer.size());
147 }
148
149 return Name;
150}
151
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000152Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000153 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000154 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000155 // If a header is not available, don't report that it maps to anything.
156 if (!Known->second.isAvailable())
Douglas Gregor51f564f2011-12-31 04:05:44 +0000157 return 0;
158
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000159 return Known->second.getModule();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000160 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000161
Douglas Gregoradb97992011-11-16 23:02:25 +0000162 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000163 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000164
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000165 // Note: as an egregious but useful hack we use the real path here, because
166 // frameworks moving from top-level frameworks to embedded frameworks tend
167 // to be symlinked from the top-level location to the embedded location,
168 // and we need to resolve lookups as if we had found the embedded location.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000169 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000170
171 // Keep walking up the directory hierarchy, looking for a directory with
172 // an umbrella header.
173 do {
174 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
175 = UmbrellaDirs.find(Dir);
176 if (KnownDir != UmbrellaDirs.end()) {
177 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000178
179 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000180 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000181 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000182 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000183 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000184
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000185 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000186 // Infer submodules for each of the directories we found between
187 // the directory of the umbrella header and the directory where
188 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000189 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000190
Douglas Gregor6a1db482011-12-09 02:04:43 +0000191 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000192 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000193 SmallString<32> NameBuf;
194 StringRef Name = sanitizeFilenameAsIdentifier(
195 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
196 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000197 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000198 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000199
200 // Associate the module and the directory.
201 UmbrellaDirs[SkippedDirs[I-1]] = Result;
202
203 // If inferred submodules export everything they import, add a
204 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000205 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000206 Result->Exports.push_back(Module::ExportDecl(0, true));
207 }
208
209 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000210 SmallString<32> NameBuf;
211 StringRef Name = sanitizeFilenameAsIdentifier(
212 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000213 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000214 Explicit).first;
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +0000215 Result->addTopHeader(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000216
217 // If inferred submodules export everything they import, add a
218 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000219 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000220 Result->Exports.push_back(Module::ExportDecl(0, true));
221 } else {
222 // Record each of the directories we stepped through as being part of
223 // the module we found, since the umbrella header covers them all.
224 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
225 UmbrellaDirs[SkippedDirs[I]] = Result;
226 }
227
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000228 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000229
230 // If a header corresponds to an unavailable module, don't report
231 // that it maps to anything.
232 if (!Result->isAvailable())
233 return 0;
234
Douglas Gregore209e502011-12-06 01:10:29 +0000235 return Result;
236 }
237
238 SkippedDirs.push_back(Dir);
239
Douglas Gregoradb97992011-11-16 23:02:25 +0000240 // Retrieve our parent path.
241 DirName = llvm::sys::path::parent_path(DirName);
242 if (DirName.empty())
243 break;
244
245 // Resolve the parent path to a directory entry.
246 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000247 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000248
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000249 return 0;
250}
251
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000252bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
253 HeadersMap::const_iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000254 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000255 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000256
257 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000258 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000259 StringRef DirName = Dir->getName();
260
261 // Keep walking up the directory hierarchy, looking for a directory with
262 // an umbrella header.
263 do {
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000264 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor51f564f2011-12-31 04:05:44 +0000265 = UmbrellaDirs.find(Dir);
266 if (KnownDir != UmbrellaDirs.end()) {
267 Module *Found = KnownDir->second;
268 if (!Found->isAvailable())
269 return true;
270
271 // Search up the module stack until we find a module with an umbrella
272 // directory.
273 Module *UmbrellaModule = Found;
274 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
275 UmbrellaModule = UmbrellaModule->Parent;
276
277 if (UmbrellaModule->InferSubmodules) {
278 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
279 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000280 SmallString<32> NameBuf;
281 StringRef Name = sanitizeFilenameAsIdentifier(
282 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
283 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000284 Found = lookupModuleQualified(Name, Found);
285 if (!Found)
286 return false;
287 if (!Found->isAvailable())
288 return true;
289 }
290
291 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000292 SmallString<32> NameBuf;
293 StringRef Name = sanitizeFilenameAsIdentifier(
294 llvm::sys::path::stem(Header->getName()),
295 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000296 Found = lookupModuleQualified(Name, Found);
297 if (!Found)
298 return false;
299 }
300
301 return !Found->isAvailable();
302 }
303
304 SkippedDirs.push_back(Dir);
305
306 // Retrieve our parent path.
307 DirName = llvm::sys::path::parent_path(DirName);
308 if (DirName.empty())
309 break;
310
311 // Resolve the parent path to a directory entry.
312 Dir = SourceMgr->getFileManager().getDirectory(DirName);
313 } while (Dir);
314
315 return false;
316}
317
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000318Module *ModuleMap::findModule(StringRef Name) const {
319 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor484535e2011-11-11 23:20:24 +0000320 if (Known != Modules.end())
321 return Known->getValue();
322
323 return 0;
324}
325
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000326Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
327 Module *Context) const {
Douglas Gregor90db2602011-12-02 01:47:07 +0000328 for(; Context; Context = Context->Parent) {
329 if (Module *Sub = lookupModuleQualified(Name, Context))
330 return Sub;
331 }
332
333 return findModule(Name);
334}
335
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000336Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor90db2602011-12-02 01:47:07 +0000337 if (!Context)
338 return findModule(Name);
339
Douglas Gregorb7a78192012-01-04 23:32:19 +0000340 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000341}
342
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000343std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000344ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
345 bool IsExplicit) {
346 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000347 if (Module *Sub = lookupModuleQualified(Name, Parent))
348 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000349
350 // Create a new module with this name.
351 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
352 IsExplicit);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000353 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000354 Modules[Name] = Result;
355 return std::make_pair(Result, true);
356}
357
Douglas Gregor82e52372012-11-06 19:39:40 +0000358bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000359 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000360 // Check whether we have already looked into the parent directory
361 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000362 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000363 inferred = InferredDirectories.find(ParentDir);
364 if (inferred == InferredDirectories.end())
365 return false;
366
367 if (!inferred->second.InferModules)
368 return false;
369
370 // We're allowed to infer for this directory, but make sure it's okay
371 // to infer this particular module.
372 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
373 inferred->second.ExcludedModules.end(),
374 Name) == inferred->second.ExcludedModules.end();
375
376 if (canInfer && inferred->second.InferSystemModules)
377 IsSystem = true;
378
379 return canInfer;
380}
381
Douglas Gregor8767dc22013-01-14 17:57:51 +0000382/// \brief For a framework module, infer the framework against which we
383/// should link.
384static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
385 FileManager &FileMgr) {
386 assert(Mod->IsFramework && "Can only infer linking for framework modules");
387 assert(!Mod->isSubFramework() &&
388 "Can only infer linking for top-level frameworks");
389
390 SmallString<128> LibName;
391 LibName += FrameworkDir->getName();
392 llvm::sys::path::append(LibName, Mod->Name);
393 if (FileMgr.getFile(LibName)) {
394 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
395 /*IsFramework=*/true));
396 }
397}
398
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000399Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000400ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000401 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000402 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000403 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000404 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000405 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
406 return Mod;
407
408 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000409
410 // If the framework has a parent path from which we're allowed to infer
411 // a framework module, do so.
412 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000413 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000414
Douglas Gregor7005b902013-01-10 01:43:00 +0000415 // Note: as an egregious but useful hack we use the real path here, because
416 // we might be looking at an embedded framework that symlinks out to a
417 // top-level framework, and we need to infer as if we were naming the
418 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000419 StringRef FrameworkDirName
420 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000421
Douglas Gregor82e52372012-11-06 19:39:40 +0000422 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000423 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000424 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000425 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000426 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
427 // Check whether we have already looked into the parent directory
428 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000429 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000430 inferred = InferredDirectories.find(ParentDir);
431 if (inferred == InferredDirectories.end()) {
432 // We haven't looked here before. Load a module map, if there is
433 // one.
434 SmallString<128> ModMapPath = Parent;
435 llvm::sys::path::append(ModMapPath, "module.map");
436 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
437 parseModuleMapFile(ModMapFile);
438 inferred = InferredDirectories.find(ParentDir);
439 }
440
441 if (inferred == InferredDirectories.end())
442 inferred = InferredDirectories.insert(
443 std::make_pair(ParentDir, InferredDirectory())).first;
444 }
445
446 if (inferred->second.InferModules) {
447 // We're allowed to infer for this directory, but make sure it's okay
448 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000449 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000450 canInfer = std::find(inferred->second.ExcludedModules.begin(),
451 inferred->second.ExcludedModules.end(),
452 Name) == inferred->second.ExcludedModules.end();
453
454 if (inferred->second.InferSystemModules)
455 IsSystem = true;
456 }
457 }
458 }
459
460 // If we're not allowed to infer a framework module, don't.
461 if (!canInfer)
462 return 0;
463 }
464
465
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000466 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000467 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000468 llvm::sys::path::append(UmbrellaName, "Headers");
469 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000470 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000471
472 // FIXME: If there's no umbrella header, we could probably scan the
473 // framework to load *everything*. But, it's not clear that this is a good
474 // idea.
475 if (!UmbrellaHeader)
476 return 0;
477
Douglas Gregorac252a32011-12-06 19:39:29 +0000478 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
479 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000480 if (IsSystem)
481 Result->IsSystem = IsSystem;
482
Douglas Gregorb7a78192012-01-04 23:32:19 +0000483 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000484 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000485
Douglas Gregor489ad432011-12-08 18:00:48 +0000486 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000487 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000488 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000489 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000490
491 // export *
492 Result->Exports.push_back(Module::ExportDecl(0, true));
493
Douglas Gregore209e502011-12-06 01:10:29 +0000494 // module * { export * }
495 Result->InferSubmodules = true;
496 Result->InferExportWildcard = true;
497
Douglas Gregorac252a32011-12-06 19:39:29 +0000498 // Look for subframeworks.
499 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000500 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000501 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000502 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000503 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000504 llvm::sys::path::native(SubframeworksDirName.str(),
505 SubframeworksDirNameNative);
506 for (llvm::sys::fs::directory_iterator
507 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000508 Dir != DirEnd && !EC; Dir.increment(EC)) {
509 if (!StringRef(Dir->path()).endswith(".framework"))
510 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000511
Douglas Gregorac252a32011-12-06 19:39:29 +0000512 if (const DirectoryEntry *SubframeworkDir
513 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000514 // Note: as an egregious but useful hack, we use the real path here and
515 // check whether it is actually a subdirectory of the parent directory.
516 // This will not be the case if the 'subframework' is actually a symlink
517 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000518 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
519 bool FoundParent = false;
520 do {
521 // Get the parent directory name.
522 SubframeworkDirName
523 = llvm::sys::path::parent_path(SubframeworkDirName);
524 if (SubframeworkDirName.empty())
525 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000526
Douglas Gregor713b7c02013-01-26 00:55:12 +0000527 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
528 FoundParent = true;
529 break;
530 }
531 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000532
Douglas Gregor713b7c02013-01-26 00:55:12 +0000533 if (!FoundParent)
534 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000535
Douglas Gregorac252a32011-12-06 19:39:29 +0000536 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000537 SmallString<32> NameBuf;
538 inferFrameworkModule(sanitizeFilenameAsIdentifier(
539 llvm::sys::path::stem(Dir->path()), NameBuf),
540 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000541 }
542 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000543
Douglas Gregor8767dc22013-01-14 17:57:51 +0000544 // If the module is a top-level framework, automatically link against the
545 // framework.
546 if (!Result->isSubFramework()) {
547 inferFrameworkLink(Result, FrameworkDir, FileMgr);
548 }
549
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000550 return Result;
551}
552
Douglas Gregore209e502011-12-06 01:10:29 +0000553void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000554 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000555 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000556 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000557}
558
Douglas Gregor77d029f2011-12-08 19:11:24 +0000559void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
560 Mod->Umbrella = UmbrellaDir;
561 UmbrellaDirs[UmbrellaDir] = Mod;
562}
563
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000564void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
565 bool Excluded) {
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000566 if (Excluded) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000567 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000568 } else {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000569 Mod->Headers.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000570 HeaderInfo.MarkFileModuleHeader(Header);
571 }
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000572 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000573}
574
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000575const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000576ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000577 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
578 return 0;
579
580 return SourceMgr->getFileEntryForID(
581 SourceMgr->getFileID(Module->DefinitionLoc));
582}
583
Douglas Gregora30cfe52011-11-11 19:10:28 +0000584void ModuleMap::dump() {
585 llvm::errs() << "Modules:";
586 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
587 MEnd = Modules.end();
588 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000589 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000590
591 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000592 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000593 H != HEnd; ++H) {
594 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000595 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000596 }
597}
598
Douglas Gregor90db2602011-12-02 01:47:07 +0000599bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
600 bool HadError = false;
601 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
602 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
603 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000604 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000605 Mod->Exports.push_back(Export);
606 else
607 HadError = true;
608 }
609 Mod->UnresolvedExports.clear();
610 return HadError;
611}
612
Douglas Gregor906d66a2013-03-20 21:10:35 +0000613bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
614 bool HadError = false;
615 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
616 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
617 Mod, Complain);
618 if (!OtherMod) {
619 HadError = true;
620 continue;
621 }
622
623 Module::Conflict Conflict;
624 Conflict.Other = OtherMod;
625 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
626 Mod->Conflicts.push_back(Conflict);
627 }
628 Mod->UnresolvedConflicts.clear();
629 return HadError;
630}
631
Douglas Gregor55988682011-12-05 16:33:54 +0000632Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
633 if (Loc.isInvalid())
634 return 0;
635
636 // Use the expansion location to determine which module we're in.
637 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
638 if (!ExpansionLoc.isFileID())
639 return 0;
640
641
642 const SourceManager &SrcMgr = Loc.getManager();
643 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000644
Douglas Gregor303aae92012-01-06 17:19:32 +0000645 while (const FileEntry *ExpansionFile
646 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
647 // Find the module that owns this header (if any).
648 if (Module *Mod = findModuleForHeader(ExpansionFile))
649 return Mod;
650
651 // No module owns this header, so look up the inclusion chain to see if
652 // any included header has an associated module.
653 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
654 if (IncludeLoc.isInvalid())
655 return 0;
656
657 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
658 }
659
660 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000661}
662
Douglas Gregora30cfe52011-11-11 19:10:28 +0000663//----------------------------------------------------------------------------//
664// Module map file parser
665//----------------------------------------------------------------------------//
666
667namespace clang {
668 /// \brief A token in a module map file.
669 struct MMToken {
670 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000671 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000672 ConfigMacros,
Douglas Gregor906d66a2013-03-20 21:10:35 +0000673 Conflict,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000674 EndOfFile,
675 HeaderKeyword,
676 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000677 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000678 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000679 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000680 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000681 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000682 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000683 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000684 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000685 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000686 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000687 StringLiteral,
688 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000689 RBrace,
690 LSquare,
691 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000692 } Kind;
693
694 unsigned Location;
695 unsigned StringLength;
696 const char *StringData;
697
698 void clear() {
699 Kind = EndOfFile;
700 Location = 0;
701 StringLength = 0;
702 StringData = 0;
703 }
704
705 bool is(TokenKind K) const { return Kind == K; }
706
707 SourceLocation getLocation() const {
708 return SourceLocation::getFromRawEncoding(Location);
709 }
710
711 StringRef getString() const {
712 return StringRef(StringData, StringLength);
713 }
714 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000715
716 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000717 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000718 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000719
720 /// \brief Whether this is a system module.
721 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000722
723 /// \brief Whether this is an exhaustive set of configuration macros.
724 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000725 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000726
Douglas Gregor82e52372012-11-06 19:39:40 +0000727
Douglas Gregora30cfe52011-11-11 19:10:28 +0000728 class ModuleMapParser {
729 Lexer &L;
730 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000731
732 /// \brief Default target information, used only for string literal
733 /// parsing.
734 const TargetInfo *Target;
735
Douglas Gregora30cfe52011-11-11 19:10:28 +0000736 DiagnosticsEngine &Diags;
737 ModuleMap &Map;
738
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000739 /// \brief The directory that this module map resides in.
740 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000741
742 /// \brief The directory containing Clang-supplied headers.
743 const DirectoryEntry *BuiltinIncludeDir;
744
Douglas Gregora30cfe52011-11-11 19:10:28 +0000745 /// \brief Whether an error occurred.
746 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000747
Douglas Gregora30cfe52011-11-11 19:10:28 +0000748 /// \brief Stores string data for the various string literals referenced
749 /// during parsing.
750 llvm::BumpPtrAllocator StringData;
751
752 /// \brief The current token.
753 MMToken Tok;
754
755 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000756 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000757
758 /// \brief Consume the current token and return its location.
759 SourceLocation consumeToken();
760
761 /// \brief Skip tokens until we reach the a token with the given kind
762 /// (or the end of the file).
763 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000764
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000765 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000766 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000767 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000768 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000769 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000770 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000771 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000772 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000773 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000774 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000775 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000776 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000777
Douglas Gregor6a1db482011-12-09 02:04:43 +0000778 const DirectoryEntry *getOverriddenHeaderSearchDir();
779
Douglas Gregora30cfe52011-11-11 19:10:28 +0000780 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000781 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000782 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000783 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000784 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000785 const DirectoryEntry *Directory,
786 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000787 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000788 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
789 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000790 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000791 Tok.clear();
792 consumeToken();
793 }
794
795 bool parseModuleMapFile();
796 };
797}
798
799SourceLocation ModuleMapParser::consumeToken() {
800retry:
801 SourceLocation Result = Tok.getLocation();
802 Tok.clear();
803
804 Token LToken;
805 L.LexFromRawLexer(LToken);
806 Tok.Location = LToken.getLocation().getRawEncoding();
807 switch (LToken.getKind()) {
808 case tok::raw_identifier:
809 Tok.StringData = LToken.getRawIdentifierData();
810 Tok.StringLength = LToken.getLength();
811 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000812 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000813 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000814 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000815 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000816 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000817 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000818 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000819 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000820 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000821 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000822 .Case("umbrella", MMToken::UmbrellaKeyword)
823 .Default(MMToken::Identifier);
824 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000825
826 case tok::comma:
827 Tok.Kind = MMToken::Comma;
828 break;
829
Douglas Gregora30cfe52011-11-11 19:10:28 +0000830 case tok::eof:
831 Tok.Kind = MMToken::EndOfFile;
832 break;
833
834 case tok::l_brace:
835 Tok.Kind = MMToken::LBrace;
836 break;
837
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000838 case tok::l_square:
839 Tok.Kind = MMToken::LSquare;
840 break;
841
Douglas Gregor90db2602011-12-02 01:47:07 +0000842 case tok::period:
843 Tok.Kind = MMToken::Period;
844 break;
845
Douglas Gregora30cfe52011-11-11 19:10:28 +0000846 case tok::r_brace:
847 Tok.Kind = MMToken::RBrace;
848 break;
849
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000850 case tok::r_square:
851 Tok.Kind = MMToken::RSquare;
852 break;
853
Douglas Gregor90db2602011-12-02 01:47:07 +0000854 case tok::star:
855 Tok.Kind = MMToken::Star;
856 break;
857
Douglas Gregora30cfe52011-11-11 19:10:28 +0000858 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000859 if (LToken.hasUDSuffix()) {
860 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
861 HadError = true;
862 goto retry;
863 }
864
Douglas Gregora30cfe52011-11-11 19:10:28 +0000865 // Parse the string literal.
866 LangOptions LangOpts;
867 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
868 if (StringLiteral.hadError)
869 goto retry;
870
871 // Copy the string literal into our string data allocator.
872 unsigned Length = StringLiteral.GetStringLength();
873 char *Saved = StringData.Allocate<char>(Length + 1);
874 memcpy(Saved, StringLiteral.GetString().data(), Length);
875 Saved[Length] = 0;
876
877 // Form the token.
878 Tok.Kind = MMToken::StringLiteral;
879 Tok.StringData = Saved;
880 Tok.StringLength = Length;
881 break;
882 }
883
884 case tok::comment:
885 goto retry;
886
887 default:
888 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
889 HadError = true;
890 goto retry;
891 }
892
893 return Result;
894}
895
896void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
897 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000898 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000899 do {
900 switch (Tok.Kind) {
901 case MMToken::EndOfFile:
902 return;
903
904 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000905 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000906 return;
907
908 ++braceDepth;
909 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000910
911 case MMToken::LSquare:
912 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
913 return;
914
915 ++squareDepth;
916 break;
917
Douglas Gregora30cfe52011-11-11 19:10:28 +0000918 case MMToken::RBrace:
919 if (braceDepth > 0)
920 --braceDepth;
921 else if (Tok.is(K))
922 return;
923 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000924
925 case MMToken::RSquare:
926 if (squareDepth > 0)
927 --squareDepth;
928 else if (Tok.is(K))
929 return;
930 break;
931
Douglas Gregora30cfe52011-11-11 19:10:28 +0000932 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000933 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000934 return;
935 break;
936 }
937
938 consumeToken();
939 } while (true);
940}
941
Douglas Gregor587986e2011-12-07 02:23:45 +0000942/// \brief Parse a module-id.
943///
944/// module-id:
945/// identifier
946/// identifier '.' module-id
947///
948/// \returns true if an error occurred, false otherwise.
949bool ModuleMapParser::parseModuleId(ModuleId &Id) {
950 Id.clear();
951 do {
952 if (Tok.is(MMToken::Identifier)) {
953 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
954 consumeToken();
955 } else {
956 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
957 return true;
958 }
959
960 if (!Tok.is(MMToken::Period))
961 break;
962
963 consumeToken();
964 } while (true);
965
966 return false;
967}
968
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000969namespace {
970 /// \brief Enumerates the known attributes.
971 enum AttributeKind {
972 /// \brief An unknown attribute.
973 AT_unknown,
974 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +0000975 AT_system,
976 /// \brief The 'exhaustive' attribute.
977 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000978 };
979}
980
Douglas Gregora30cfe52011-11-11 19:10:28 +0000981/// \brief Parse a module declaration.
982///
983/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000984/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
985/// { module-member* }
986///
Douglas Gregora30cfe52011-11-11 19:10:28 +0000987/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +0000988/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000989/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +0000990/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +0000991/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000992/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +0000993///
994/// submodule-declaration:
995/// module-declaration
996/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000997void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +0000998 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
999 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +00001000 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001001 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001002 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001003 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001004
Douglas Gregord620a842011-12-06 17:16:41 +00001005 // Parse 'explicit' keyword, if present.
1006 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001007 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001008 Explicit = true;
1009 }
1010
1011 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001012 if (Tok.is(MMToken::FrameworkKeyword)) {
1013 consumeToken();
1014 Framework = true;
1015 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001016
1017 // Parse 'module' keyword.
1018 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001019 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001020 consumeToken();
1021 HadError = true;
1022 return;
1023 }
1024 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001025
1026 // If we have a wildcard for the module name, this is an inferred submodule.
1027 // Parse it.
1028 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001029 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001030
1031 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001032 ModuleId Id;
1033 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001034 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001035 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001036 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001037
Douglas Gregor587986e2011-12-07 02:23:45 +00001038 if (ActiveModule) {
1039 if (Id.size() > 1) {
1040 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1041 << SourceRange(Id.front().second, Id.back().second);
1042
1043 HadError = true;
1044 return;
1045 }
1046 } else if (Id.size() == 1 && Explicit) {
1047 // Top-level modules can't be explicit.
1048 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1049 Explicit = false;
1050 ExplicitLoc = SourceLocation();
1051 HadError = true;
1052 }
1053
1054 Module *PreviousActiveModule = ActiveModule;
1055 if (Id.size() > 1) {
1056 // This module map defines a submodule. Go find the module of which it
1057 // is a submodule.
1058 ActiveModule = 0;
1059 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1060 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1061 ActiveModule = Next;
1062 continue;
1063 }
1064
1065 if (ActiveModule) {
1066 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1067 << Id[I].first << ActiveModule->getTopLevelModule();
1068 } else {
1069 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1070 }
1071 HadError = true;
1072 return;
1073 }
1074 }
1075
1076 StringRef ModuleName = Id.back().first;
1077 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001078
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001079 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001080 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001081 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001082
Douglas Gregora30cfe52011-11-11 19:10:28 +00001083 // Parse the opening brace.
1084 if (!Tok.is(MMToken::LBrace)) {
1085 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1086 << ModuleName;
1087 HadError = true;
1088 return;
1089 }
1090 SourceLocation LBraceLoc = consumeToken();
1091
1092 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001093 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001094 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1095 // Skip the module definition.
1096 skipUntil(MMToken::RBrace);
1097 if (Tok.is(MMToken::RBrace))
1098 consumeToken();
1099 else {
1100 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1101 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1102 HadError = true;
1103 }
1104 return;
1105 }
1106
Douglas Gregora30cfe52011-11-11 19:10:28 +00001107 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1108 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001109 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001110
1111 // Skip the module definition.
1112 skipUntil(MMToken::RBrace);
1113 if (Tok.is(MMToken::RBrace))
1114 consumeToken();
1115
1116 HadError = true;
1117 return;
1118 }
1119
1120 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001121 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1122 Explicit).first;
1123 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001124 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001125 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001126
1127 bool Done = false;
1128 do {
1129 switch (Tok.Kind) {
1130 case MMToken::EndOfFile:
1131 case MMToken::RBrace:
1132 Done = true;
1133 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001134
1135 case MMToken::ConfigMacros:
1136 parseConfigMacros();
1137 break;
1138
Douglas Gregor906d66a2013-03-20 21:10:35 +00001139 case MMToken::Conflict:
1140 parseConflict();
1141 break;
1142
Douglas Gregora30cfe52011-11-11 19:10:28 +00001143 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001144 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001145 case MMToken::ModuleKeyword:
1146 parseModuleDecl();
1147 break;
1148
Douglas Gregor90db2602011-12-02 01:47:07 +00001149 case MMToken::ExportKeyword:
1150 parseExportDecl();
1151 break;
1152
Douglas Gregor51f564f2011-12-31 04:05:44 +00001153 case MMToken::RequiresKeyword:
1154 parseRequiresDecl();
1155 break;
1156
Douglas Gregor77d029f2011-12-08 19:11:24 +00001157 case MMToken::UmbrellaKeyword: {
1158 SourceLocation UmbrellaLoc = consumeToken();
1159 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001160 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001161 else
1162 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001163 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001164 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001165
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001166 case MMToken::ExcludeKeyword: {
1167 SourceLocation ExcludeLoc = consumeToken();
1168 if (Tok.is(MMToken::HeaderKeyword)) {
1169 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1170 } else {
1171 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1172 << "exclude";
1173 }
1174 break;
1175 }
1176
Douglas Gregor489ad432011-12-08 18:00:48 +00001177 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001178 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001179 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001180
1181 case MMToken::LinkKeyword:
1182 parseLinkDecl();
1183 break;
1184
Douglas Gregora30cfe52011-11-11 19:10:28 +00001185 default:
1186 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1187 consumeToken();
1188 break;
1189 }
1190 } while (!Done);
1191
1192 if (Tok.is(MMToken::RBrace))
1193 consumeToken();
1194 else {
1195 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1196 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1197 HadError = true;
1198 }
1199
Douglas Gregor8767dc22013-01-14 17:57:51 +00001200 // If the active module is a top-level framework, and there are no link
1201 // libraries, automatically link against the framework.
1202 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1203 ActiveModule->LinkLibraries.empty()) {
1204 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1205 }
1206
Douglas Gregor587986e2011-12-07 02:23:45 +00001207 // We're done parsing this module. Pop back to the previous module.
1208 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001209}
Douglas Gregord620a842011-12-06 17:16:41 +00001210
Douglas Gregor51f564f2011-12-31 04:05:44 +00001211/// \brief Parse a requires declaration.
1212///
1213/// requires-declaration:
1214/// 'requires' feature-list
1215///
1216/// feature-list:
1217/// identifier ',' feature-list
1218/// identifier
1219void ModuleMapParser::parseRequiresDecl() {
1220 assert(Tok.is(MMToken::RequiresKeyword));
1221
1222 // Parse 'requires' keyword.
1223 consumeToken();
1224
1225 // Parse the feature-list.
1226 do {
1227 if (!Tok.is(MMToken::Identifier)) {
1228 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1229 HadError = true;
1230 return;
1231 }
1232
1233 // Consume the feature name.
1234 std::string Feature = Tok.getString();
1235 consumeToken();
1236
1237 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001238 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001239
1240 if (!Tok.is(MMToken::Comma))
1241 break;
1242
1243 // Consume the comma.
1244 consumeToken();
1245 } while (true);
1246}
1247
Douglas Gregord620a842011-12-06 17:16:41 +00001248/// \brief Append to \p Paths the set of paths needed to get to the
1249/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001250static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001251 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001252 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001253 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001254 for (; Mod; Mod = Mod->Parent) {
1255 if (Mod->IsFramework)
1256 Paths.push_back(Mod->Name);
1257 }
1258
1259 if (Paths.empty())
1260 return;
1261
1262 // Add Frameworks/Name.framework for each subframework.
1263 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1264 llvm::sys::path::append(Path, "Frameworks");
1265 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1266 }
1267}
1268
Douglas Gregor2f04f182012-02-02 18:42:48 +00001269/// \brief Determine whether the given file name is the name of a builtin
1270/// header, supplied by Clang to replace, override, or augment existing system
1271/// headers.
1272static bool isBuiltinHeader(StringRef FileName) {
1273 return llvm::StringSwitch<bool>(FileName)
1274 .Case("float.h", true)
1275 .Case("iso646.h", true)
1276 .Case("limits.h", true)
1277 .Case("stdalign.h", true)
1278 .Case("stdarg.h", true)
1279 .Case("stdbool.h", true)
1280 .Case("stddef.h", true)
1281 .Case("stdint.h", true)
1282 .Case("tgmath.h", true)
1283 .Case("unwind.h", true)
1284 .Default(false);
1285}
1286
Douglas Gregora30cfe52011-11-11 19:10:28 +00001287/// \brief Parse a header declaration.
1288///
1289/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001290/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001291/// 'exclude'[opt] 'header' string-literal
1292void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1293 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001294 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001295 consumeToken();
1296
Douglas Gregor489ad432011-12-08 18:00:48 +00001297 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001298 bool Exclude = ExcludeLoc.isValid();
1299 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001300 // Parse the header name.
1301 if (!Tok.is(MMToken::StringLiteral)) {
1302 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1303 << "header";
1304 HadError = true;
1305 return;
1306 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001307 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001308 SourceLocation FileNameLoc = consumeToken();
1309
Douglas Gregor77d029f2011-12-08 19:11:24 +00001310 // Check whether we already have an umbrella.
1311 if (Umbrella && ActiveModule->Umbrella) {
1312 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1313 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001314 HadError = true;
1315 return;
1316 }
1317
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001318 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001319 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001320 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001321 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001322 if (llvm::sys::path::is_absolute(FileName)) {
1323 PathName = FileName;
1324 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001325 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1326 PathName = Dir->getName();
1327 llvm::sys::path::append(PathName, FileName);
1328 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001329 } else {
1330 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001331 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001332 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001333
Douglas Gregord620a842011-12-06 17:16:41 +00001334 if (ActiveModule->isPartOfFramework()) {
1335 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001336
1337 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001338 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001339 llvm::sys::path::append(PathName, FileName);
1340 File = SourceMgr.getFileManager().getFile(PathName);
1341
1342 if (!File) {
1343 // Check whether this file is in the private headers.
1344 PathName.resize(PathLength);
1345 llvm::sys::path::append(PathName, "PrivateHeaders");
1346 llvm::sys::path::append(PathName, FileName);
1347 File = SourceMgr.getFileManager().getFile(PathName);
1348 }
1349 } else {
1350 // Lookup for normal headers.
1351 llvm::sys::path::append(PathName, FileName);
1352 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001353
1354 // If this is a system module with a top-level header, this header
1355 // may have a counterpart (or replacement) in the set of headers
1356 // supplied by Clang. Find that builtin header.
1357 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1358 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001359 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001360 llvm::sys::path::append(BuiltinPathName, FileName);
1361 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1362
1363 // If Clang supplies this header but the underlying system does not,
1364 // just silently swap in our builtin version. Otherwise, we'll end
1365 // up adding both (later).
1366 if (!File && BuiltinFile) {
1367 File = BuiltinFile;
1368 BuiltinFile = 0;
1369 }
1370 }
Douglas Gregord620a842011-12-06 17:16:41 +00001371 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001372 }
Douglas Gregora8654052011-11-17 22:09:43 +00001373
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001374 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1375 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001376 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001377 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001378 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001379 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001380 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001381 } else if (Umbrella) {
1382 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001383 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001384 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001385 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001386 HadError = true;
1387 } else {
1388 // Record this umbrella header.
1389 Map.setUmbrellaHeader(ActiveModule, File);
1390 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001391 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001392 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001393 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001394
1395 // If there is a builtin counterpart to this file, add it now.
1396 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001397 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001398 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001399 } else if (!Exclude) {
1400 // Ignore excluded header files. They're optional anyway.
1401
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001402 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001403 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001404 HadError = true;
1405 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001406}
1407
Douglas Gregor77d029f2011-12-08 19:11:24 +00001408/// \brief Parse an umbrella directory declaration.
1409///
1410/// umbrella-dir-declaration:
1411/// umbrella string-literal
1412void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1413 // Parse the directory name.
1414 if (!Tok.is(MMToken::StringLiteral)) {
1415 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1416 << "umbrella";
1417 HadError = true;
1418 return;
1419 }
1420
1421 std::string DirName = Tok.getString();
1422 SourceLocation DirNameLoc = consumeToken();
1423
1424 // Check whether we already have an umbrella.
1425 if (ActiveModule->Umbrella) {
1426 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1427 << ActiveModule->getFullModuleName();
1428 HadError = true;
1429 return;
1430 }
1431
1432 // Look for this file.
1433 const DirectoryEntry *Dir = 0;
1434 if (llvm::sys::path::is_absolute(DirName))
1435 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1436 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001437 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001438 PathName = Directory->getName();
1439 llvm::sys::path::append(PathName, DirName);
1440 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1441 }
1442
1443 if (!Dir) {
1444 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1445 << DirName;
1446 HadError = true;
1447 return;
1448 }
1449
1450 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1451 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1452 << OwningModule->getFullModuleName();
1453 HadError = true;
1454 return;
1455 }
1456
1457 // Record this umbrella directory.
1458 Map.setUmbrellaDir(ActiveModule, Dir);
1459}
1460
Douglas Gregor90db2602011-12-02 01:47:07 +00001461/// \brief Parse a module export declaration.
1462///
1463/// export-declaration:
1464/// 'export' wildcard-module-id
1465///
1466/// wildcard-module-id:
1467/// identifier
1468/// '*'
1469/// identifier '.' wildcard-module-id
1470void ModuleMapParser::parseExportDecl() {
1471 assert(Tok.is(MMToken::ExportKeyword));
1472 SourceLocation ExportLoc = consumeToken();
1473
1474 // Parse the module-id with an optional wildcard at the end.
1475 ModuleId ParsedModuleId;
1476 bool Wildcard = false;
1477 do {
1478 if (Tok.is(MMToken::Identifier)) {
1479 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1480 Tok.getLocation()));
1481 consumeToken();
1482
1483 if (Tok.is(MMToken::Period)) {
1484 consumeToken();
1485 continue;
1486 }
1487
1488 break;
1489 }
1490
1491 if(Tok.is(MMToken::Star)) {
1492 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001493 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001494 break;
1495 }
1496
1497 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1498 HadError = true;
1499 return;
1500 } while (true);
1501
1502 Module::UnresolvedExportDecl Unresolved = {
1503 ExportLoc, ParsedModuleId, Wildcard
1504 };
1505 ActiveModule->UnresolvedExports.push_back(Unresolved);
1506}
1507
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001508/// \brief Parse a link declaration.
1509///
1510/// module-declaration:
1511/// 'link' 'framework'[opt] string-literal
1512void ModuleMapParser::parseLinkDecl() {
1513 assert(Tok.is(MMToken::LinkKeyword));
1514 SourceLocation LinkLoc = consumeToken();
1515
1516 // Parse the optional 'framework' keyword.
1517 bool IsFramework = false;
1518 if (Tok.is(MMToken::FrameworkKeyword)) {
1519 consumeToken();
1520 IsFramework = true;
1521 }
1522
1523 // Parse the library name
1524 if (!Tok.is(MMToken::StringLiteral)) {
1525 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1526 << IsFramework << SourceRange(LinkLoc);
1527 HadError = true;
1528 return;
1529 }
1530
1531 std::string LibraryName = Tok.getString();
1532 consumeToken();
1533 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1534 IsFramework));
1535}
1536
Douglas Gregor63a72682013-03-20 00:22:05 +00001537/// \brief Parse a configuration macro declaration.
1538///
1539/// module-declaration:
1540/// 'config_macros' attributes[opt] config-macro-list?
1541///
1542/// config-macro-list:
1543/// identifier (',' identifier)?
1544void ModuleMapParser::parseConfigMacros() {
1545 assert(Tok.is(MMToken::ConfigMacros));
1546 SourceLocation ConfigMacrosLoc = consumeToken();
1547
1548 // Only top-level modules can have configuration macros.
1549 if (ActiveModule->Parent) {
1550 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1551 }
1552
1553 // Parse the optional attributes.
1554 Attributes Attrs;
1555 parseOptionalAttributes(Attrs);
1556 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1557 ActiveModule->ConfigMacrosExhaustive = true;
1558 }
1559
1560 // If we don't have an identifier, we're done.
1561 if (!Tok.is(MMToken::Identifier))
1562 return;
1563
1564 // Consume the first identifier.
1565 if (!ActiveModule->Parent) {
1566 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1567 }
1568 consumeToken();
1569
1570 do {
1571 // If there's a comma, consume it.
1572 if (!Tok.is(MMToken::Comma))
1573 break;
1574 consumeToken();
1575
1576 // We expect to see a macro name here.
1577 if (!Tok.is(MMToken::Identifier)) {
1578 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1579 break;
1580 }
1581
1582 // Consume the macro name.
1583 if (!ActiveModule->Parent) {
1584 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1585 }
1586 consumeToken();
1587 } while (true);
1588}
1589
Douglas Gregor906d66a2013-03-20 21:10:35 +00001590/// \brief Format a module-id into a string.
1591static std::string formatModuleId(const ModuleId &Id) {
1592 std::string result;
1593 {
1594 llvm::raw_string_ostream OS(result);
1595
1596 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1597 if (I)
1598 OS << ".";
1599 OS << Id[I].first;
1600 }
1601 }
1602
1603 return result;
1604}
1605
1606/// \brief Parse a conflict declaration.
1607///
1608/// module-declaration:
1609/// 'conflict' module-id ',' string-literal
1610void ModuleMapParser::parseConflict() {
1611 assert(Tok.is(MMToken::Conflict));
1612 SourceLocation ConflictLoc = consumeToken();
1613 Module::UnresolvedConflict Conflict;
1614
1615 // Parse the module-id.
1616 if (parseModuleId(Conflict.Id))
1617 return;
1618
1619 // Parse the ','.
1620 if (!Tok.is(MMToken::Comma)) {
1621 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1622 << SourceRange(ConflictLoc);
1623 return;
1624 }
1625 consumeToken();
1626
1627 // Parse the message.
1628 if (!Tok.is(MMToken::StringLiteral)) {
1629 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1630 << formatModuleId(Conflict.Id);
1631 return;
1632 }
1633 Conflict.Message = Tok.getString().str();
1634 consumeToken();
1635
1636 // Add this unresolved conflict.
1637 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1638}
1639
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001640/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001641///
1642/// module-declaration:
1643/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1644/// { inferred-module-member* }
1645///
1646/// inferred-module-member:
1647/// 'export' '*'
1648/// 'exclude' identifier
1649void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001650 assert(Tok.is(MMToken::Star));
1651 SourceLocation StarLoc = consumeToken();
1652 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001653
Douglas Gregor1e123682011-12-05 22:27:44 +00001654 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001655 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001656 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1657 Failed = true;
1658 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001659
1660 if (ActiveModule) {
1661 // Inferred modules must have umbrella directories.
1662 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1663 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1664 Failed = true;
1665 }
1666
1667 // Check for redefinition of an inferred module.
1668 if (!Failed && ActiveModule->InferSubmodules) {
1669 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1670 if (ActiveModule->InferredSubmoduleLoc.isValid())
1671 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1672 diag::note_mmap_prev_definition);
1673 Failed = true;
1674 }
1675
1676 // Check for the 'framework' keyword, which is not permitted here.
1677 if (Framework) {
1678 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1679 Framework = false;
1680 }
1681 } else if (Explicit) {
1682 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1683 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001684 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001685
Douglas Gregor1e123682011-12-05 22:27:44 +00001686 // If there were any problems with this inferred submodule, skip its body.
1687 if (Failed) {
1688 if (Tok.is(MMToken::LBrace)) {
1689 consumeToken();
1690 skipUntil(MMToken::RBrace);
1691 if (Tok.is(MMToken::RBrace))
1692 consumeToken();
1693 }
1694 HadError = true;
1695 return;
1696 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001697
1698 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001699 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001700 parseOptionalAttributes(Attrs);
1701
1702 if (ActiveModule) {
1703 // Note that we have an inferred submodule.
1704 ActiveModule->InferSubmodules = true;
1705 ActiveModule->InferredSubmoduleLoc = StarLoc;
1706 ActiveModule->InferExplicitSubmodules = Explicit;
1707 } else {
1708 // We'll be inferring framework modules for this directory.
1709 Map.InferredDirectories[Directory].InferModules = true;
1710 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1711 }
1712
Douglas Gregor1e123682011-12-05 22:27:44 +00001713 // Parse the opening brace.
1714 if (!Tok.is(MMToken::LBrace)) {
1715 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1716 HadError = true;
1717 return;
1718 }
1719 SourceLocation LBraceLoc = consumeToken();
1720
1721 // Parse the body of the inferred submodule.
1722 bool Done = false;
1723 do {
1724 switch (Tok.Kind) {
1725 case MMToken::EndOfFile:
1726 case MMToken::RBrace:
1727 Done = true;
1728 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001729
1730 case MMToken::ExcludeKeyword: {
1731 if (ActiveModule) {
1732 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001733 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001734 consumeToken();
1735 break;
1736 }
1737
1738 consumeToken();
1739 if (!Tok.is(MMToken::Identifier)) {
1740 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1741 break;
1742 }
1743
1744 Map.InferredDirectories[Directory].ExcludedModules
1745 .push_back(Tok.getString());
1746 consumeToken();
1747 break;
1748 }
1749
1750 case MMToken::ExportKeyword:
1751 if (!ActiveModule) {
1752 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001753 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001754 consumeToken();
1755 break;
1756 }
1757
Douglas Gregor1e123682011-12-05 22:27:44 +00001758 consumeToken();
1759 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001760 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001761 else
1762 Diags.Report(Tok.getLocation(),
1763 diag::err_mmap_expected_export_wildcard);
1764 consumeToken();
1765 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001766
Douglas Gregor1e123682011-12-05 22:27:44 +00001767 case MMToken::ExplicitKeyword:
1768 case MMToken::ModuleKeyword:
1769 case MMToken::HeaderKeyword:
1770 case MMToken::UmbrellaKeyword:
1771 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001772 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001773 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001774 consumeToken();
1775 break;
1776 }
1777 } while (!Done);
1778
1779 if (Tok.is(MMToken::RBrace))
1780 consumeToken();
1781 else {
1782 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1783 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1784 HadError = true;
1785 }
1786}
1787
Douglas Gregor82e52372012-11-06 19:39:40 +00001788/// \brief Parse optional attributes.
1789///
1790/// attributes:
1791/// attribute attributes
1792/// attribute
1793///
1794/// attribute:
1795/// [ identifier ]
1796///
1797/// \param Attrs Will be filled in with the parsed attributes.
1798///
1799/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001800bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001801 bool HadError = false;
1802
1803 while (Tok.is(MMToken::LSquare)) {
1804 // Consume the '['.
1805 SourceLocation LSquareLoc = consumeToken();
1806
1807 // Check whether we have an attribute name here.
1808 if (!Tok.is(MMToken::Identifier)) {
1809 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1810 skipUntil(MMToken::RSquare);
1811 if (Tok.is(MMToken::RSquare))
1812 consumeToken();
1813 HadError = true;
1814 }
1815
1816 // Decode the attribute name.
1817 AttributeKind Attribute
1818 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001819 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00001820 .Case("system", AT_system)
1821 .Default(AT_unknown);
1822 switch (Attribute) {
1823 case AT_unknown:
1824 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1825 << Tok.getString();
1826 break;
1827
1828 case AT_system:
1829 Attrs.IsSystem = true;
1830 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001831
1832 case AT_exhaustive:
1833 Attrs.IsExhaustive = true;
1834 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001835 }
1836 consumeToken();
1837
1838 // Consume the ']'.
1839 if (!Tok.is(MMToken::RSquare)) {
1840 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1841 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1842 skipUntil(MMToken::RSquare);
1843 HadError = true;
1844 }
1845
1846 if (Tok.is(MMToken::RSquare))
1847 consumeToken();
1848 }
1849
1850 return HadError;
1851}
1852
Douglas Gregor6a1db482011-12-09 02:04:43 +00001853/// \brief If there is a specific header search directory due the presence
1854/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1855const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1856 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1857 // If we have an umbrella directory, use that.
1858 if (Mod->hasUmbrellaDir())
1859 return Mod->getUmbrellaDir();
1860
1861 // If we have a framework directory, stop looking.
1862 if (Mod->IsFramework)
1863 return 0;
1864 }
1865
1866 return 0;
1867}
1868
Douglas Gregora30cfe52011-11-11 19:10:28 +00001869/// \brief Parse a module map file.
1870///
1871/// module-map-file:
1872/// module-declaration*
1873bool ModuleMapParser::parseModuleMapFile() {
1874 do {
1875 switch (Tok.Kind) {
1876 case MMToken::EndOfFile:
1877 return HadError;
1878
Douglas Gregor587986e2011-12-07 02:23:45 +00001879 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001880 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001881 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001882 parseModuleDecl();
1883 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001884
Douglas Gregor51f564f2011-12-31 04:05:44 +00001885 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00001886 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00001887 case MMToken::Conflict:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001888 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001889 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001890 case MMToken::HeaderKeyword:
1891 case MMToken::Identifier:
1892 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001893 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001894 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001895 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001896 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001897 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001898 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001899 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001900 case MMToken::StringLiteral:
1901 case MMToken::UmbrellaKeyword:
1902 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1903 HadError = true;
1904 consumeToken();
1905 break;
1906 }
1907 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001908}
1909
1910bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001911 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1912 = ParsedModuleMap.find(File);
1913 if (Known != ParsedModuleMap.end())
1914 return Known->second;
1915
Douglas Gregordc58aa72012-01-30 06:01:29 +00001916 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001917 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1918 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1919 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001920 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001921
1922 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001923 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1924 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001925 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001926 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001927 bool Result = Parser.parseModuleMapFile();
1928 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001929 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001930 return Result;
1931}