1 //===--- 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"
15 #include "clang/Basic/CharInfo.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/DiagnosticOptions.h"
18 #include "clang/Basic/FileManager.h"
19 #include "clang/Basic/TargetInfo.h"
20 #include "clang/Basic/TargetOptions.h"
21 #include "clang/Lex/HeaderSearch.h"
22 #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"
27 #include "llvm/Support/Allocator.h"
28 #include "llvm/Support/FileSystem.h"
29 #include "llvm/Support/Host.h"
30 #include "llvm/Support/PathV2.h"
31 #include "llvm/Support/raw_ostream.h"
32 #include <stdlib.h>
33 #if defined(LLVM_ON_UNIX)
34 #include <limits.h>
35 #endif
36 using namespace clang;
37
38 Module::ExportDecl
resolveExport(Module * Mod,const Module::UnresolvedExportDecl & Unresolved,bool Complain) const39 ModuleMap::resolveExport(Module *Mod,
40 const Module::UnresolvedExportDecl &Unresolved,
41 bool Complain) const {
42 // 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
48 // Find the starting module.
49 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
50 if (!Context) {
51 if (Complain)
52 Diags->Report(Unresolved.Id[0].second,
53 diag::err_mmap_missing_module_unqualified)
54 << Unresolved.Id[0].first << Mod->getFullModuleName();
55
56 return Module::ExportDecl();
57 }
58
59 // Dig into the module path.
60 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
61 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
62 Context);
63 if (!Sub) {
64 if (Complain)
65 Diags->Report(Unresolved.Id[I].second,
66 diag::err_mmap_missing_module_qualified)
67 << Unresolved.Id[I].first << Context->getFullModuleName()
68 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
69
70 return Module::ExportDecl();
71 }
72
73 Context = Sub;
74 }
75
76 return Module::ExportDecl(Context, Unresolved.Wildcard);
77 }
78
ModuleMap(FileManager & FileMgr,const DiagnosticConsumer & DC,const LangOptions & LangOpts,const TargetInfo * Target,HeaderSearch & HeaderInfo)79 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
80 const LangOptions &LangOpts, const TargetInfo *Target,
81 HeaderSearch &HeaderInfo)
82 : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
83 BuiltinIncludeDir(0)
84 {
85 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
86 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
87 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
88 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
89 SourceMgr = new SourceManager(*Diags, FileMgr);
90 }
91
~ModuleMap()92 ModuleMap::~ModuleMap() {
93 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
94 IEnd = Modules.end();
95 I != IEnd; ++I) {
96 delete I->getValue();
97 }
98
99 delete SourceMgr;
100 }
101
setTarget(const TargetInfo & Target)102 void ModuleMap::setTarget(const TargetInfo &Target) {
103 assert((!this->Target || this->Target == &Target) &&
104 "Improper target override");
105 this->Target = &Target;
106 }
107
108 /// \brief "Sanitize" a filename so that it can be used as an identifier.
sanitizeFilenameAsIdentifier(StringRef Name,SmallVectorImpl<char> & Buffer)109 static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
110 SmallVectorImpl<char> &Buffer) {
111 if (Name.empty())
112 return Name;
113
114 if (!isValidIdentifier(Name)) {
115 // If we don't already have something with the form of an identifier,
116 // create a buffer with the sanitized name.
117 Buffer.clear();
118 if (isDigit(Name[0]))
119 Buffer.push_back('_');
120 Buffer.reserve(Buffer.size() + Name.size());
121 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
122 if (isIdentifierBody(Name[I]))
123 Buffer.push_back(Name[I]);
124 else
125 Buffer.push_back('_');
126 }
127
128 Name = StringRef(Buffer.data(), Buffer.size());
129 }
130
131 while (llvm::StringSwitch<bool>(Name)
132 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
133 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
134 #include "clang/Basic/TokenKinds.def"
135 .Default(false)) {
136 if (Name.data() != Buffer.data())
137 Buffer.append(Name.begin(), Name.end());
138 Buffer.push_back('_');
139 Name = StringRef(Buffer.data(), Buffer.size());
140 }
141
142 return Name;
143 }
144
findModuleForHeader(const FileEntry * File)145 Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
146 HeadersMap::iterator Known = Headers.find(File);
147 if (Known != Headers.end()) {
148 // If a header is not available, don't report that it maps to anything.
149 if (!Known->second.isAvailable())
150 return 0;
151
152 return Known->second.getModule();
153 }
154
155 const DirectoryEntry *Dir = File->getDir();
156 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
157
158 // Note: as an egregious but useful hack we use the real path here, because
159 // frameworks moving from top-level frameworks to embedded frameworks tend
160 // to be symlinked from the top-level location to the embedded location,
161 // and we need to resolve lookups as if we had found the embedded location.
162 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
163
164 // Keep walking up the directory hierarchy, looking for a directory with
165 // an umbrella header.
166 do {
167 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
168 = UmbrellaDirs.find(Dir);
169 if (KnownDir != UmbrellaDirs.end()) {
170 Module *Result = KnownDir->second;
171
172 // Search up the module stack until we find a module with an umbrella
173 // directory.
174 Module *UmbrellaModule = Result;
175 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
176 UmbrellaModule = UmbrellaModule->Parent;
177
178 if (UmbrellaModule->InferSubmodules) {
179 // Infer submodules for each of the directories we found between
180 // the directory of the umbrella header and the directory where
181 // the actual header is located.
182 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
183
184 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
185 // Find or create the module that corresponds to this directory name.
186 SmallString<32> NameBuf;
187 StringRef Name = sanitizeFilenameAsIdentifier(
188 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
189 NameBuf);
190 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
191 Explicit).first;
192
193 // Associate the module and the directory.
194 UmbrellaDirs[SkippedDirs[I-1]] = Result;
195
196 // If inferred submodules export everything they import, add a
197 // wildcard to the set of exports.
198 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
199 Result->Exports.push_back(Module::ExportDecl(0, true));
200 }
201
202 // Infer a submodule with the same name as this header file.
203 SmallString<32> NameBuf;
204 StringRef Name = sanitizeFilenameAsIdentifier(
205 llvm::sys::path::stem(File->getName()), NameBuf);
206 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
207 Explicit).first;
208 Result->addTopHeader(File);
209
210 // If inferred submodules export everything they import, add a
211 // wildcard to the set of exports.
212 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
213 Result->Exports.push_back(Module::ExportDecl(0, true));
214 } else {
215 // Record each of the directories we stepped through as being part of
216 // the module we found, since the umbrella header covers them all.
217 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
218 UmbrellaDirs[SkippedDirs[I]] = Result;
219 }
220
221 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
222
223 // If a header corresponds to an unavailable module, don't report
224 // that it maps to anything.
225 if (!Result->isAvailable())
226 return 0;
227
228 return Result;
229 }
230
231 SkippedDirs.push_back(Dir);
232
233 // Retrieve our parent path.
234 DirName = llvm::sys::path::parent_path(DirName);
235 if (DirName.empty())
236 break;
237
238 // Resolve the parent path to a directory entry.
239 Dir = SourceMgr->getFileManager().getDirectory(DirName);
240 } while (Dir);
241
242 return 0;
243 }
244
isHeaderInUnavailableModule(const FileEntry * Header) const245 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
246 HeadersMap::const_iterator Known = Headers.find(Header);
247 if (Known != Headers.end())
248 return !Known->second.isAvailable();
249
250 const DirectoryEntry *Dir = Header->getDir();
251 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
252 StringRef DirName = Dir->getName();
253
254 // Keep walking up the directory hierarchy, looking for a directory with
255 // an umbrella header.
256 do {
257 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
258 = UmbrellaDirs.find(Dir);
259 if (KnownDir != UmbrellaDirs.end()) {
260 Module *Found = KnownDir->second;
261 if (!Found->isAvailable())
262 return true;
263
264 // Search up the module stack until we find a module with an umbrella
265 // directory.
266 Module *UmbrellaModule = Found;
267 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
268 UmbrellaModule = UmbrellaModule->Parent;
269
270 if (UmbrellaModule->InferSubmodules) {
271 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
272 // Find or create the module that corresponds to this directory name.
273 SmallString<32> NameBuf;
274 StringRef Name = sanitizeFilenameAsIdentifier(
275 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
276 NameBuf);
277 Found = lookupModuleQualified(Name, Found);
278 if (!Found)
279 return false;
280 if (!Found->isAvailable())
281 return true;
282 }
283
284 // Infer a submodule with the same name as this header file.
285 SmallString<32> NameBuf;
286 StringRef Name = sanitizeFilenameAsIdentifier(
287 llvm::sys::path::stem(Header->getName()),
288 NameBuf);
289 Found = lookupModuleQualified(Name, Found);
290 if (!Found)
291 return false;
292 }
293
294 return !Found->isAvailable();
295 }
296
297 SkippedDirs.push_back(Dir);
298
299 // Retrieve our parent path.
300 DirName = llvm::sys::path::parent_path(DirName);
301 if (DirName.empty())
302 break;
303
304 // Resolve the parent path to a directory entry.
305 Dir = SourceMgr->getFileManager().getDirectory(DirName);
306 } while (Dir);
307
308 return false;
309 }
310
findModule(StringRef Name) const311 Module *ModuleMap::findModule(StringRef Name) const {
312 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
313 if (Known != Modules.end())
314 return Known->getValue();
315
316 return 0;
317 }
318
lookupModuleUnqualified(StringRef Name,Module * Context) const319 Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
320 Module *Context) const {
321 for(; Context; Context = Context->Parent) {
322 if (Module *Sub = lookupModuleQualified(Name, Context))
323 return Sub;
324 }
325
326 return findModule(Name);
327 }
328
lookupModuleQualified(StringRef Name,Module * Context) const329 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
330 if (!Context)
331 return findModule(Name);
332
333 return Context->findSubmodule(Name);
334 }
335
336 std::pair<Module *, bool>
findOrCreateModule(StringRef Name,Module * Parent,bool IsFramework,bool IsExplicit)337 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
338 bool IsExplicit) {
339 // Try to find an existing module with this name.
340 if (Module *Sub = lookupModuleQualified(Name, Parent))
341 return std::make_pair(Sub, false);
342
343 // Create a new module with this name.
344 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
345 IsExplicit);
346 if (!Parent)
347 Modules[Name] = Result;
348 return std::make_pair(Result, true);
349 }
350
canInferFrameworkModule(const DirectoryEntry * ParentDir,StringRef Name,bool & IsSystem) const351 bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
352 StringRef Name, bool &IsSystem) const {
353 // Check whether we have already looked into the parent directory
354 // for a module map.
355 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
356 inferred = InferredDirectories.find(ParentDir);
357 if (inferred == InferredDirectories.end())
358 return false;
359
360 if (!inferred->second.InferModules)
361 return false;
362
363 // We're allowed to infer for this directory, but make sure it's okay
364 // to infer this particular module.
365 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
366 inferred->second.ExcludedModules.end(),
367 Name) == inferred->second.ExcludedModules.end();
368
369 if (canInfer && inferred->second.InferSystemModules)
370 IsSystem = true;
371
372 return canInfer;
373 }
374
375 /// \brief For a framework module, infer the framework against which we
376 /// should link.
inferFrameworkLink(Module * Mod,const DirectoryEntry * FrameworkDir,FileManager & FileMgr)377 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
378 FileManager &FileMgr) {
379 assert(Mod->IsFramework && "Can only infer linking for framework modules");
380 assert(!Mod->isSubFramework() &&
381 "Can only infer linking for top-level frameworks");
382
383 SmallString<128> LibName;
384 LibName += FrameworkDir->getName();
385 llvm::sys::path::append(LibName, Mod->Name);
386 if (FileMgr.getFile(LibName)) {
387 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
388 /*IsFramework=*/true));
389 }
390 }
391
392 Module *
inferFrameworkModule(StringRef ModuleName,const DirectoryEntry * FrameworkDir,bool IsSystem,Module * Parent)393 ModuleMap::inferFrameworkModule(StringRef ModuleName,
394 const DirectoryEntry *FrameworkDir,
395 bool IsSystem,
396 Module *Parent) {
397 // Check whether we've already found this module.
398 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
399 return Mod;
400
401 FileManager &FileMgr = SourceMgr->getFileManager();
402
403 // If the framework has a parent path from which we're allowed to infer
404 // a framework module, do so.
405 if (!Parent) {
406 // Determine whether we're allowed to infer a module map.
407
408 // Note: as an egregious but useful hack we use the real path here, because
409 // we might be looking at an embedded framework that symlinks out to a
410 // top-level framework, and we need to infer as if we were naming the
411 // top-level framework.
412 StringRef FrameworkDirName
413 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
414
415 bool canInfer = false;
416 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
417 // Figure out the parent path.
418 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
419 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
420 // Check whether we have already looked into the parent directory
421 // for a module map.
422 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
423 inferred = InferredDirectories.find(ParentDir);
424 if (inferred == InferredDirectories.end()) {
425 // We haven't looked here before. Load a module map, if there is
426 // one.
427 SmallString<128> ModMapPath = Parent;
428 llvm::sys::path::append(ModMapPath, "module.map");
429 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
430 parseModuleMapFile(ModMapFile);
431 inferred = InferredDirectories.find(ParentDir);
432 }
433
434 if (inferred == InferredDirectories.end())
435 inferred = InferredDirectories.insert(
436 std::make_pair(ParentDir, InferredDirectory())).first;
437 }
438
439 if (inferred->second.InferModules) {
440 // We're allowed to infer for this directory, but make sure it's okay
441 // to infer this particular module.
442 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
443 canInfer = std::find(inferred->second.ExcludedModules.begin(),
444 inferred->second.ExcludedModules.end(),
445 Name) == inferred->second.ExcludedModules.end();
446
447 if (inferred->second.InferSystemModules)
448 IsSystem = true;
449 }
450 }
451 }
452
453 // If we're not allowed to infer a framework module, don't.
454 if (!canInfer)
455 return 0;
456 }
457
458
459 // Look for an umbrella header.
460 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
461 llvm::sys::path::append(UmbrellaName, "Headers");
462 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
463 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
464
465 // FIXME: If there's no umbrella header, we could probably scan the
466 // framework to load *everything*. But, it's not clear that this is a good
467 // idea.
468 if (!UmbrellaHeader)
469 return 0;
470
471 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
472 /*IsFramework=*/true, /*IsExplicit=*/false);
473 if (IsSystem)
474 Result->IsSystem = IsSystem;
475
476 if (!Parent)
477 Modules[ModuleName] = Result;
478
479 // umbrella header "umbrella-header-name"
480 Result->Umbrella = UmbrellaHeader;
481 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
482 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
483
484 // export *
485 Result->Exports.push_back(Module::ExportDecl(0, true));
486
487 // module * { export * }
488 Result->InferSubmodules = true;
489 Result->InferExportWildcard = true;
490
491 // Look for subframeworks.
492 llvm::error_code EC;
493 SmallString<128> SubframeworksDirName
494 = StringRef(FrameworkDir->getName());
495 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
496 SmallString<128> SubframeworksDirNameNative;
497 llvm::sys::path::native(SubframeworksDirName.str(),
498 SubframeworksDirNameNative);
499 for (llvm::sys::fs::directory_iterator
500 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
501 Dir != DirEnd && !EC; Dir.increment(EC)) {
502 if (!StringRef(Dir->path()).endswith(".framework"))
503 continue;
504
505 if (const DirectoryEntry *SubframeworkDir
506 = FileMgr.getDirectory(Dir->path())) {
507 // Note: as an egregious but useful hack, we use the real path here and
508 // check whether it is actually a subdirectory of the parent directory.
509 // This will not be the case if the 'subframework' is actually a symlink
510 // out to a top-level framework.
511 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
512 bool FoundParent = false;
513 do {
514 // Get the parent directory name.
515 SubframeworkDirName
516 = llvm::sys::path::parent_path(SubframeworkDirName);
517 if (SubframeworkDirName.empty())
518 break;
519
520 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
521 FoundParent = true;
522 break;
523 }
524 } while (true);
525
526 if (!FoundParent)
527 continue;
528
529 // FIXME: Do we want to warn about subframeworks without umbrella headers?
530 SmallString<32> NameBuf;
531 inferFrameworkModule(sanitizeFilenameAsIdentifier(
532 llvm::sys::path::stem(Dir->path()), NameBuf),
533 SubframeworkDir, IsSystem, Result);
534 }
535 }
536
537 // If the module is a top-level framework, automatically link against the
538 // framework.
539 if (!Result->isSubFramework()) {
540 inferFrameworkLink(Result, FrameworkDir, FileMgr);
541 }
542
543 return Result;
544 }
545
setUmbrellaHeader(Module * Mod,const FileEntry * UmbrellaHeader)546 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
547 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
548 Mod->Umbrella = UmbrellaHeader;
549 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
550 }
551
setUmbrellaDir(Module * Mod,const DirectoryEntry * UmbrellaDir)552 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
553 Mod->Umbrella = UmbrellaDir;
554 UmbrellaDirs[UmbrellaDir] = Mod;
555 }
556
addHeader(Module * Mod,const FileEntry * Header,bool Excluded)557 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
558 bool Excluded) {
559 if (Excluded) {
560 Mod->ExcludedHeaders.push_back(Header);
561 } else {
562 Mod->Headers.push_back(Header);
563 HeaderInfo.MarkFileModuleHeader(Header);
564 }
565 Headers[Header] = KnownHeader(Mod, Excluded);
566 }
567
568 const FileEntry *
getContainingModuleMapFile(Module * Module) const569 ModuleMap::getContainingModuleMapFile(Module *Module) const {
570 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
571 return 0;
572
573 return SourceMgr->getFileEntryForID(
574 SourceMgr->getFileID(Module->DefinitionLoc));
575 }
576
dump()577 void ModuleMap::dump() {
578 llvm::errs() << "Modules:";
579 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
580 MEnd = Modules.end();
581 M != MEnd; ++M)
582 M->getValue()->print(llvm::errs(), 2);
583
584 llvm::errs() << "Headers:";
585 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
586 H != HEnd; ++H) {
587 llvm::errs() << " \"" << H->first->getName() << "\" -> "
588 << H->second.getModule()->getFullModuleName() << "\n";
589 }
590 }
591
resolveExports(Module * Mod,bool Complain)592 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
593 bool HadError = false;
594 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
595 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
596 Complain);
597 if (Export.getPointer() || Export.getInt())
598 Mod->Exports.push_back(Export);
599 else
600 HadError = true;
601 }
602 Mod->UnresolvedExports.clear();
603 return HadError;
604 }
605
inferModuleFromLocation(FullSourceLoc Loc)606 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
607 if (Loc.isInvalid())
608 return 0;
609
610 // Use the expansion location to determine which module we're in.
611 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
612 if (!ExpansionLoc.isFileID())
613 return 0;
614
615
616 const SourceManager &SrcMgr = Loc.getManager();
617 FileID ExpansionFileID = ExpansionLoc.getFileID();
618
619 while (const FileEntry *ExpansionFile
620 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
621 // Find the module that owns this header (if any).
622 if (Module *Mod = findModuleForHeader(ExpansionFile))
623 return Mod;
624
625 // No module owns this header, so look up the inclusion chain to see if
626 // any included header has an associated module.
627 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
628 if (IncludeLoc.isInvalid())
629 return 0;
630
631 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
632 }
633
634 return 0;
635 }
636
637 //----------------------------------------------------------------------------//
638 // Module map file parser
639 //----------------------------------------------------------------------------//
640
641 namespace clang {
642 /// \brief A token in a module map file.
643 struct MMToken {
644 enum TokenKind {
645 Comma,
646 EndOfFile,
647 HeaderKeyword,
648 Identifier,
649 ExcludeKeyword,
650 ExplicitKeyword,
651 ExportKeyword,
652 FrameworkKeyword,
653 LinkKeyword,
654 ModuleKeyword,
655 Period,
656 UmbrellaKeyword,
657 RequiresKeyword,
658 Star,
659 StringLiteral,
660 LBrace,
661 RBrace,
662 LSquare,
663 RSquare
664 } Kind;
665
666 unsigned Location;
667 unsigned StringLength;
668 const char *StringData;
669
clearclang::MMToken670 void clear() {
671 Kind = EndOfFile;
672 Location = 0;
673 StringLength = 0;
674 StringData = 0;
675 }
676
isclang::MMToken677 bool is(TokenKind K) const { return Kind == K; }
678
getLocationclang::MMToken679 SourceLocation getLocation() const {
680 return SourceLocation::getFromRawEncoding(Location);
681 }
682
getStringclang::MMToken683 StringRef getString() const {
684 return StringRef(StringData, StringLength);
685 }
686 };
687
688 /// \brief The set of attributes that can be attached to a module.
689 struct Attributes {
Attributesclang::Attributes690 Attributes() : IsSystem() { }
691
692 /// \brief Whether this is a system module.
693 unsigned IsSystem : 1;
694 };
695
696
697 class ModuleMapParser {
698 Lexer &L;
699 SourceManager &SourceMgr;
700
701 /// \brief Default target information, used only for string literal
702 /// parsing.
703 const TargetInfo *Target;
704
705 DiagnosticsEngine &Diags;
706 ModuleMap ⤅
707
708 /// \brief The directory that this module map resides in.
709 const DirectoryEntry *Directory;
710
711 /// \brief The directory containing Clang-supplied headers.
712 const DirectoryEntry *BuiltinIncludeDir;
713
714 /// \brief Whether an error occurred.
715 bool HadError;
716
717 /// \brief Stores string data for the various string literals referenced
718 /// during parsing.
719 llvm::BumpPtrAllocator StringData;
720
721 /// \brief The current token.
722 MMToken Tok;
723
724 /// \brief The active module.
725 Module *ActiveModule;
726
727 /// \brief Consume the current token and return its location.
728 SourceLocation consumeToken();
729
730 /// \brief Skip tokens until we reach the a token with the given kind
731 /// (or the end of the file).
732 void skipUntil(MMToken::TokenKind K);
733
734 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
735 bool parseModuleId(ModuleId &Id);
736 void parseModuleDecl();
737 void parseRequiresDecl();
738 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
739 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
740 void parseExportDecl();
741 void parseLinkDecl();
742 void parseInferredModuleDecl(bool Framework, bool Explicit);
743 bool parseOptionalAttributes(Attributes &Attrs);
744
745 const DirectoryEntry *getOverriddenHeaderSearchDir();
746
747 public:
ModuleMapParser(Lexer & L,SourceManager & SourceMgr,const TargetInfo * Target,DiagnosticsEngine & Diags,ModuleMap & Map,const DirectoryEntry * Directory,const DirectoryEntry * BuiltinIncludeDir)748 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
749 const TargetInfo *Target,
750 DiagnosticsEngine &Diags,
751 ModuleMap &Map,
752 const DirectoryEntry *Directory,
753 const DirectoryEntry *BuiltinIncludeDir)
754 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
755 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
756 HadError(false), ActiveModule(0)
757 {
758 Tok.clear();
759 consumeToken();
760 }
761
762 bool parseModuleMapFile();
763 };
764 }
765
consumeToken()766 SourceLocation ModuleMapParser::consumeToken() {
767 retry:
768 SourceLocation Result = Tok.getLocation();
769 Tok.clear();
770
771 Token LToken;
772 L.LexFromRawLexer(LToken);
773 Tok.Location = LToken.getLocation().getRawEncoding();
774 switch (LToken.getKind()) {
775 case tok::raw_identifier:
776 Tok.StringData = LToken.getRawIdentifierData();
777 Tok.StringLength = LToken.getLength();
778 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
779 .Case("header", MMToken::HeaderKeyword)
780 .Case("exclude", MMToken::ExcludeKeyword)
781 .Case("explicit", MMToken::ExplicitKeyword)
782 .Case("export", MMToken::ExportKeyword)
783 .Case("framework", MMToken::FrameworkKeyword)
784 .Case("link", MMToken::LinkKeyword)
785 .Case("module", MMToken::ModuleKeyword)
786 .Case("requires", MMToken::RequiresKeyword)
787 .Case("umbrella", MMToken::UmbrellaKeyword)
788 .Default(MMToken::Identifier);
789 break;
790
791 case tok::comma:
792 Tok.Kind = MMToken::Comma;
793 break;
794
795 case tok::eof:
796 Tok.Kind = MMToken::EndOfFile;
797 break;
798
799 case tok::l_brace:
800 Tok.Kind = MMToken::LBrace;
801 break;
802
803 case tok::l_square:
804 Tok.Kind = MMToken::LSquare;
805 break;
806
807 case tok::period:
808 Tok.Kind = MMToken::Period;
809 break;
810
811 case tok::r_brace:
812 Tok.Kind = MMToken::RBrace;
813 break;
814
815 case tok::r_square:
816 Tok.Kind = MMToken::RSquare;
817 break;
818
819 case tok::star:
820 Tok.Kind = MMToken::Star;
821 break;
822
823 case tok::string_literal: {
824 if (LToken.hasUDSuffix()) {
825 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
826 HadError = true;
827 goto retry;
828 }
829
830 // Parse the string literal.
831 LangOptions LangOpts;
832 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target);
833 if (StringLiteral.hadError)
834 goto retry;
835
836 // Copy the string literal into our string data allocator.
837 unsigned Length = StringLiteral.GetStringLength();
838 char *Saved = StringData.Allocate<char>(Length + 1);
839 memcpy(Saved, StringLiteral.GetString().data(), Length);
840 Saved[Length] = 0;
841
842 // Form the token.
843 Tok.Kind = MMToken::StringLiteral;
844 Tok.StringData = Saved;
845 Tok.StringLength = Length;
846 break;
847 }
848
849 case tok::comment:
850 goto retry;
851
852 default:
853 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
854 HadError = true;
855 goto retry;
856 }
857
858 return Result;
859 }
860
skipUntil(MMToken::TokenKind K)861 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
862 unsigned braceDepth = 0;
863 unsigned squareDepth = 0;
864 do {
865 switch (Tok.Kind) {
866 case MMToken::EndOfFile:
867 return;
868
869 case MMToken::LBrace:
870 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
871 return;
872
873 ++braceDepth;
874 break;
875
876 case MMToken::LSquare:
877 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
878 return;
879
880 ++squareDepth;
881 break;
882
883 case MMToken::RBrace:
884 if (braceDepth > 0)
885 --braceDepth;
886 else if (Tok.is(K))
887 return;
888 break;
889
890 case MMToken::RSquare:
891 if (squareDepth > 0)
892 --squareDepth;
893 else if (Tok.is(K))
894 return;
895 break;
896
897 default:
898 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
899 return;
900 break;
901 }
902
903 consumeToken();
904 } while (true);
905 }
906
907 /// \brief Parse a module-id.
908 ///
909 /// module-id:
910 /// identifier
911 /// identifier '.' module-id
912 ///
913 /// \returns true if an error occurred, false otherwise.
parseModuleId(ModuleId & Id)914 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
915 Id.clear();
916 do {
917 if (Tok.is(MMToken::Identifier)) {
918 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
919 consumeToken();
920 } else {
921 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
922 return true;
923 }
924
925 if (!Tok.is(MMToken::Period))
926 break;
927
928 consumeToken();
929 } while (true);
930
931 return false;
932 }
933
934 namespace {
935 /// \brief Enumerates the known attributes.
936 enum AttributeKind {
937 /// \brief An unknown attribute.
938 AT_unknown,
939 /// \brief The 'system' attribute.
940 AT_system
941 };
942 }
943
944 /// \brief Parse a module declaration.
945 ///
946 /// module-declaration:
947 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
948 /// { module-member* }
949 ///
950 /// module-member:
951 /// requires-declaration
952 /// header-declaration
953 /// submodule-declaration
954 /// export-declaration
955 /// link-declaration
956 ///
957 /// submodule-declaration:
958 /// module-declaration
959 /// inferred-submodule-declaration
parseModuleDecl()960 void ModuleMapParser::parseModuleDecl() {
961 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
962 Tok.is(MMToken::FrameworkKeyword));
963 // Parse 'explicit' or 'framework' keyword, if present.
964 SourceLocation ExplicitLoc;
965 bool Explicit = false;
966 bool Framework = false;
967
968 // Parse 'explicit' keyword, if present.
969 if (Tok.is(MMToken::ExplicitKeyword)) {
970 ExplicitLoc = consumeToken();
971 Explicit = true;
972 }
973
974 // Parse 'framework' keyword, if present.
975 if (Tok.is(MMToken::FrameworkKeyword)) {
976 consumeToken();
977 Framework = true;
978 }
979
980 // Parse 'module' keyword.
981 if (!Tok.is(MMToken::ModuleKeyword)) {
982 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
983 consumeToken();
984 HadError = true;
985 return;
986 }
987 consumeToken(); // 'module' keyword
988
989 // If we have a wildcard for the module name, this is an inferred submodule.
990 // Parse it.
991 if (Tok.is(MMToken::Star))
992 return parseInferredModuleDecl(Framework, Explicit);
993
994 // Parse the module name.
995 ModuleId Id;
996 if (parseModuleId(Id)) {
997 HadError = true;
998 return;
999 }
1000
1001 if (ActiveModule) {
1002 if (Id.size() > 1) {
1003 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1004 << SourceRange(Id.front().second, Id.back().second);
1005
1006 HadError = true;
1007 return;
1008 }
1009 } else if (Id.size() == 1 && Explicit) {
1010 // Top-level modules can't be explicit.
1011 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1012 Explicit = false;
1013 ExplicitLoc = SourceLocation();
1014 HadError = true;
1015 }
1016
1017 Module *PreviousActiveModule = ActiveModule;
1018 if (Id.size() > 1) {
1019 // This module map defines a submodule. Go find the module of which it
1020 // is a submodule.
1021 ActiveModule = 0;
1022 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1023 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1024 ActiveModule = Next;
1025 continue;
1026 }
1027
1028 if (ActiveModule) {
1029 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1030 << Id[I].first << ActiveModule->getTopLevelModule();
1031 } else {
1032 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1033 }
1034 HadError = true;
1035 return;
1036 }
1037 }
1038
1039 StringRef ModuleName = Id.back().first;
1040 SourceLocation ModuleNameLoc = Id.back().second;
1041
1042 // Parse the optional attribute list.
1043 Attributes Attrs;
1044 parseOptionalAttributes(Attrs);
1045
1046 // Parse the opening brace.
1047 if (!Tok.is(MMToken::LBrace)) {
1048 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1049 << ModuleName;
1050 HadError = true;
1051 return;
1052 }
1053 SourceLocation LBraceLoc = consumeToken();
1054
1055 // Determine whether this (sub)module has already been defined.
1056 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1057 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1058 // Skip the module definition.
1059 skipUntil(MMToken::RBrace);
1060 if (Tok.is(MMToken::RBrace))
1061 consumeToken();
1062 else {
1063 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1064 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1065 HadError = true;
1066 }
1067 return;
1068 }
1069
1070 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1071 << ModuleName;
1072 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1073
1074 // Skip the module definition.
1075 skipUntil(MMToken::RBrace);
1076 if (Tok.is(MMToken::RBrace))
1077 consumeToken();
1078
1079 HadError = true;
1080 return;
1081 }
1082
1083 // Start defining this module.
1084 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1085 Explicit).first;
1086 ActiveModule->DefinitionLoc = ModuleNameLoc;
1087 if (Attrs.IsSystem)
1088 ActiveModule->IsSystem = true;
1089
1090 bool Done = false;
1091 do {
1092 switch (Tok.Kind) {
1093 case MMToken::EndOfFile:
1094 case MMToken::RBrace:
1095 Done = true;
1096 break;
1097
1098 case MMToken::ExplicitKeyword:
1099 case MMToken::FrameworkKeyword:
1100 case MMToken::ModuleKeyword:
1101 parseModuleDecl();
1102 break;
1103
1104 case MMToken::ExportKeyword:
1105 parseExportDecl();
1106 break;
1107
1108 case MMToken::RequiresKeyword:
1109 parseRequiresDecl();
1110 break;
1111
1112 case MMToken::UmbrellaKeyword: {
1113 SourceLocation UmbrellaLoc = consumeToken();
1114 if (Tok.is(MMToken::HeaderKeyword))
1115 parseHeaderDecl(UmbrellaLoc, SourceLocation());
1116 else
1117 parseUmbrellaDirDecl(UmbrellaLoc);
1118 break;
1119 }
1120
1121 case MMToken::ExcludeKeyword: {
1122 SourceLocation ExcludeLoc = consumeToken();
1123 if (Tok.is(MMToken::HeaderKeyword)) {
1124 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1125 } else {
1126 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1127 << "exclude";
1128 }
1129 break;
1130 }
1131
1132 case MMToken::HeaderKeyword:
1133 parseHeaderDecl(SourceLocation(), SourceLocation());
1134 break;
1135
1136 case MMToken::LinkKeyword:
1137 parseLinkDecl();
1138 break;
1139
1140 default:
1141 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1142 consumeToken();
1143 break;
1144 }
1145 } while (!Done);
1146
1147 if (Tok.is(MMToken::RBrace))
1148 consumeToken();
1149 else {
1150 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1151 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1152 HadError = true;
1153 }
1154
1155 // If the active module is a top-level framework, and there are no link
1156 // libraries, automatically link against the framework.
1157 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1158 ActiveModule->LinkLibraries.empty()) {
1159 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1160 }
1161
1162 // We're done parsing this module. Pop back to the previous module.
1163 ActiveModule = PreviousActiveModule;
1164 }
1165
1166 /// \brief Parse a requires declaration.
1167 ///
1168 /// requires-declaration:
1169 /// 'requires' feature-list
1170 ///
1171 /// feature-list:
1172 /// identifier ',' feature-list
1173 /// identifier
parseRequiresDecl()1174 void ModuleMapParser::parseRequiresDecl() {
1175 assert(Tok.is(MMToken::RequiresKeyword));
1176
1177 // Parse 'requires' keyword.
1178 consumeToken();
1179
1180 // Parse the feature-list.
1181 do {
1182 if (!Tok.is(MMToken::Identifier)) {
1183 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1184 HadError = true;
1185 return;
1186 }
1187
1188 // Consume the feature name.
1189 std::string Feature = Tok.getString();
1190 consumeToken();
1191
1192 // Add this feature.
1193 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
1194
1195 if (!Tok.is(MMToken::Comma))
1196 break;
1197
1198 // Consume the comma.
1199 consumeToken();
1200 } while (true);
1201 }
1202
1203 /// \brief Append to \p Paths the set of paths needed to get to the
1204 /// subframework in which the given module lives.
appendSubframeworkPaths(Module * Mod,SmallVectorImpl<char> & Path)1205 static void appendSubframeworkPaths(Module *Mod,
1206 SmallVectorImpl<char> &Path) {
1207 // Collect the framework names from the given module to the top-level module.
1208 SmallVector<StringRef, 2> Paths;
1209 for (; Mod; Mod = Mod->Parent) {
1210 if (Mod->IsFramework)
1211 Paths.push_back(Mod->Name);
1212 }
1213
1214 if (Paths.empty())
1215 return;
1216
1217 // Add Frameworks/Name.framework for each subframework.
1218 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1219 llvm::sys::path::append(Path, "Frameworks");
1220 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1221 }
1222 }
1223
1224 /// \brief Determine whether the given file name is the name of a builtin
1225 /// header, supplied by Clang to replace, override, or augment existing system
1226 /// headers.
isBuiltinHeader(StringRef FileName)1227 static bool isBuiltinHeader(StringRef FileName) {
1228 return llvm::StringSwitch<bool>(FileName)
1229 .Case("float.h", true)
1230 .Case("iso646.h", true)
1231 .Case("limits.h", true)
1232 .Case("stdalign.h", true)
1233 .Case("stdarg.h", true)
1234 .Case("stdbool.h", true)
1235 .Case("stddef.h", true)
1236 .Case("stdint.h", true)
1237 .Case("tgmath.h", true)
1238 .Case("unwind.h", true)
1239 .Default(false);
1240 }
1241
1242 /// \brief Parse a header declaration.
1243 ///
1244 /// header-declaration:
1245 /// 'umbrella'[opt] 'header' string-literal
1246 /// 'exclude'[opt] 'header' string-literal
parseHeaderDecl(SourceLocation UmbrellaLoc,SourceLocation ExcludeLoc)1247 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1248 SourceLocation ExcludeLoc) {
1249 assert(Tok.is(MMToken::HeaderKeyword));
1250 consumeToken();
1251
1252 bool Umbrella = UmbrellaLoc.isValid();
1253 bool Exclude = ExcludeLoc.isValid();
1254 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
1255 // Parse the header name.
1256 if (!Tok.is(MMToken::StringLiteral)) {
1257 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1258 << "header";
1259 HadError = true;
1260 return;
1261 }
1262 std::string FileName = Tok.getString();
1263 SourceLocation FileNameLoc = consumeToken();
1264
1265 // Check whether we already have an umbrella.
1266 if (Umbrella && ActiveModule->Umbrella) {
1267 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1268 << ActiveModule->getFullModuleName();
1269 HadError = true;
1270 return;
1271 }
1272
1273 // Look for this file.
1274 const FileEntry *File = 0;
1275 const FileEntry *BuiltinFile = 0;
1276 SmallString<128> PathName;
1277 if (llvm::sys::path::is_absolute(FileName)) {
1278 PathName = FileName;
1279 File = SourceMgr.getFileManager().getFile(PathName);
1280 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1281 PathName = Dir->getName();
1282 llvm::sys::path::append(PathName, FileName);
1283 File = SourceMgr.getFileManager().getFile(PathName);
1284 } else {
1285 // Search for the header file within the search directory.
1286 PathName = Directory->getName();
1287 unsigned PathLength = PathName.size();
1288
1289 if (ActiveModule->isPartOfFramework()) {
1290 appendSubframeworkPaths(ActiveModule, PathName);
1291
1292 // Check whether this file is in the public headers.
1293 llvm::sys::path::append(PathName, "Headers");
1294 llvm::sys::path::append(PathName, FileName);
1295 File = SourceMgr.getFileManager().getFile(PathName);
1296
1297 if (!File) {
1298 // Check whether this file is in the private headers.
1299 PathName.resize(PathLength);
1300 llvm::sys::path::append(PathName, "PrivateHeaders");
1301 llvm::sys::path::append(PathName, FileName);
1302 File = SourceMgr.getFileManager().getFile(PathName);
1303 }
1304 } else {
1305 // Lookup for normal headers.
1306 llvm::sys::path::append(PathName, FileName);
1307 File = SourceMgr.getFileManager().getFile(PathName);
1308
1309 // If this is a system module with a top-level header, this header
1310 // may have a counterpart (or replacement) in the set of headers
1311 // supplied by Clang. Find that builtin header.
1312 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1313 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
1314 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1315 llvm::sys::path::append(BuiltinPathName, FileName);
1316 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1317
1318 // If Clang supplies this header but the underlying system does not,
1319 // just silently swap in our builtin version. Otherwise, we'll end
1320 // up adding both (later).
1321 if (!File && BuiltinFile) {
1322 File = BuiltinFile;
1323 BuiltinFile = 0;
1324 }
1325 }
1326 }
1327 }
1328
1329 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1330 // Come up with a lazy way to do this.
1331 if (File) {
1332 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
1333 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
1334 << FileName << OwningModule.getModule()->getFullModuleName();
1335 HadError = true;
1336 } else if (Umbrella) {
1337 const DirectoryEntry *UmbrellaDir = File->getDir();
1338 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1339 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1340 << UmbrellaModule->getFullModuleName();
1341 HadError = true;
1342 } else {
1343 // Record this umbrella header.
1344 Map.setUmbrellaHeader(ActiveModule, File);
1345 }
1346 } else {
1347 // Record this header.
1348 Map.addHeader(ActiveModule, File, Exclude);
1349
1350 // If there is a builtin counterpart to this file, add it now.
1351 if (BuiltinFile)
1352 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
1353 }
1354 } else if (!Exclude) {
1355 // Ignore excluded header files. They're optional anyway.
1356
1357 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1358 << Umbrella << FileName;
1359 HadError = true;
1360 }
1361 }
1362
1363 /// \brief Parse an umbrella directory declaration.
1364 ///
1365 /// umbrella-dir-declaration:
1366 /// umbrella string-literal
parseUmbrellaDirDecl(SourceLocation UmbrellaLoc)1367 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1368 // Parse the directory name.
1369 if (!Tok.is(MMToken::StringLiteral)) {
1370 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1371 << "umbrella";
1372 HadError = true;
1373 return;
1374 }
1375
1376 std::string DirName = Tok.getString();
1377 SourceLocation DirNameLoc = consumeToken();
1378
1379 // Check whether we already have an umbrella.
1380 if (ActiveModule->Umbrella) {
1381 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1382 << ActiveModule->getFullModuleName();
1383 HadError = true;
1384 return;
1385 }
1386
1387 // Look for this file.
1388 const DirectoryEntry *Dir = 0;
1389 if (llvm::sys::path::is_absolute(DirName))
1390 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1391 else {
1392 SmallString<128> PathName;
1393 PathName = Directory->getName();
1394 llvm::sys::path::append(PathName, DirName);
1395 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1396 }
1397
1398 if (!Dir) {
1399 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1400 << DirName;
1401 HadError = true;
1402 return;
1403 }
1404
1405 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1406 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1407 << OwningModule->getFullModuleName();
1408 HadError = true;
1409 return;
1410 }
1411
1412 // Record this umbrella directory.
1413 Map.setUmbrellaDir(ActiveModule, Dir);
1414 }
1415
1416 /// \brief Parse a module export declaration.
1417 ///
1418 /// export-declaration:
1419 /// 'export' wildcard-module-id
1420 ///
1421 /// wildcard-module-id:
1422 /// identifier
1423 /// '*'
1424 /// identifier '.' wildcard-module-id
parseExportDecl()1425 void ModuleMapParser::parseExportDecl() {
1426 assert(Tok.is(MMToken::ExportKeyword));
1427 SourceLocation ExportLoc = consumeToken();
1428
1429 // Parse the module-id with an optional wildcard at the end.
1430 ModuleId ParsedModuleId;
1431 bool Wildcard = false;
1432 do {
1433 if (Tok.is(MMToken::Identifier)) {
1434 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1435 Tok.getLocation()));
1436 consumeToken();
1437
1438 if (Tok.is(MMToken::Period)) {
1439 consumeToken();
1440 continue;
1441 }
1442
1443 break;
1444 }
1445
1446 if(Tok.is(MMToken::Star)) {
1447 Wildcard = true;
1448 consumeToken();
1449 break;
1450 }
1451
1452 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1453 HadError = true;
1454 return;
1455 } while (true);
1456
1457 Module::UnresolvedExportDecl Unresolved = {
1458 ExportLoc, ParsedModuleId, Wildcard
1459 };
1460 ActiveModule->UnresolvedExports.push_back(Unresolved);
1461 }
1462
1463 /// \brief Parse a link declaration.
1464 ///
1465 /// module-declaration:
1466 /// 'link' 'framework'[opt] string-literal
parseLinkDecl()1467 void ModuleMapParser::parseLinkDecl() {
1468 assert(Tok.is(MMToken::LinkKeyword));
1469 SourceLocation LinkLoc = consumeToken();
1470
1471 // Parse the optional 'framework' keyword.
1472 bool IsFramework = false;
1473 if (Tok.is(MMToken::FrameworkKeyword)) {
1474 consumeToken();
1475 IsFramework = true;
1476 }
1477
1478 // Parse the library name
1479 if (!Tok.is(MMToken::StringLiteral)) {
1480 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1481 << IsFramework << SourceRange(LinkLoc);
1482 HadError = true;
1483 return;
1484 }
1485
1486 std::string LibraryName = Tok.getString();
1487 consumeToken();
1488 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1489 IsFramework));
1490 }
1491
1492 /// \brief Parse an inferred module declaration (wildcard modules).
1493 ///
1494 /// module-declaration:
1495 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1496 /// { inferred-module-member* }
1497 ///
1498 /// inferred-module-member:
1499 /// 'export' '*'
1500 /// 'exclude' identifier
parseInferredModuleDecl(bool Framework,bool Explicit)1501 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
1502 assert(Tok.is(MMToken::Star));
1503 SourceLocation StarLoc = consumeToken();
1504 bool Failed = false;
1505
1506 // Inferred modules must be submodules.
1507 if (!ActiveModule && !Framework) {
1508 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1509 Failed = true;
1510 }
1511
1512 if (ActiveModule) {
1513 // Inferred modules must have umbrella directories.
1514 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1515 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1516 Failed = true;
1517 }
1518
1519 // Check for redefinition of an inferred module.
1520 if (!Failed && ActiveModule->InferSubmodules) {
1521 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1522 if (ActiveModule->InferredSubmoduleLoc.isValid())
1523 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1524 diag::note_mmap_prev_definition);
1525 Failed = true;
1526 }
1527
1528 // Check for the 'framework' keyword, which is not permitted here.
1529 if (Framework) {
1530 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1531 Framework = false;
1532 }
1533 } else if (Explicit) {
1534 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1535 Explicit = false;
1536 }
1537
1538 // If there were any problems with this inferred submodule, skip its body.
1539 if (Failed) {
1540 if (Tok.is(MMToken::LBrace)) {
1541 consumeToken();
1542 skipUntil(MMToken::RBrace);
1543 if (Tok.is(MMToken::RBrace))
1544 consumeToken();
1545 }
1546 HadError = true;
1547 return;
1548 }
1549
1550 // Parse optional attributes.
1551 Attributes Attrs;
1552 parseOptionalAttributes(Attrs);
1553
1554 if (ActiveModule) {
1555 // Note that we have an inferred submodule.
1556 ActiveModule->InferSubmodules = true;
1557 ActiveModule->InferredSubmoduleLoc = StarLoc;
1558 ActiveModule->InferExplicitSubmodules = Explicit;
1559 } else {
1560 // We'll be inferring framework modules for this directory.
1561 Map.InferredDirectories[Directory].InferModules = true;
1562 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1563 }
1564
1565 // Parse the opening brace.
1566 if (!Tok.is(MMToken::LBrace)) {
1567 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1568 HadError = true;
1569 return;
1570 }
1571 SourceLocation LBraceLoc = consumeToken();
1572
1573 // Parse the body of the inferred submodule.
1574 bool Done = false;
1575 do {
1576 switch (Tok.Kind) {
1577 case MMToken::EndOfFile:
1578 case MMToken::RBrace:
1579 Done = true;
1580 break;
1581
1582 case MMToken::ExcludeKeyword: {
1583 if (ActiveModule) {
1584 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1585 << (ActiveModule != 0);
1586 consumeToken();
1587 break;
1588 }
1589
1590 consumeToken();
1591 if (!Tok.is(MMToken::Identifier)) {
1592 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1593 break;
1594 }
1595
1596 Map.InferredDirectories[Directory].ExcludedModules
1597 .push_back(Tok.getString());
1598 consumeToken();
1599 break;
1600 }
1601
1602 case MMToken::ExportKeyword:
1603 if (!ActiveModule) {
1604 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1605 << (ActiveModule != 0);
1606 consumeToken();
1607 break;
1608 }
1609
1610 consumeToken();
1611 if (Tok.is(MMToken::Star))
1612 ActiveModule->InferExportWildcard = true;
1613 else
1614 Diags.Report(Tok.getLocation(),
1615 diag::err_mmap_expected_export_wildcard);
1616 consumeToken();
1617 break;
1618
1619 case MMToken::ExplicitKeyword:
1620 case MMToken::ModuleKeyword:
1621 case MMToken::HeaderKeyword:
1622 case MMToken::UmbrellaKeyword:
1623 default:
1624 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1625 << (ActiveModule != 0);
1626 consumeToken();
1627 break;
1628 }
1629 } while (!Done);
1630
1631 if (Tok.is(MMToken::RBrace))
1632 consumeToken();
1633 else {
1634 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1635 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1636 HadError = true;
1637 }
1638 }
1639
1640 /// \brief Parse optional attributes.
1641 ///
1642 /// attributes:
1643 /// attribute attributes
1644 /// attribute
1645 ///
1646 /// attribute:
1647 /// [ identifier ]
1648 ///
1649 /// \param Attrs Will be filled in with the parsed attributes.
1650 ///
1651 /// \returns true if an error occurred, false otherwise.
parseOptionalAttributes(Attributes & Attrs)1652 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
1653 bool HadError = false;
1654
1655 while (Tok.is(MMToken::LSquare)) {
1656 // Consume the '['.
1657 SourceLocation LSquareLoc = consumeToken();
1658
1659 // Check whether we have an attribute name here.
1660 if (!Tok.is(MMToken::Identifier)) {
1661 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1662 skipUntil(MMToken::RSquare);
1663 if (Tok.is(MMToken::RSquare))
1664 consumeToken();
1665 HadError = true;
1666 }
1667
1668 // Decode the attribute name.
1669 AttributeKind Attribute
1670 = llvm::StringSwitch<AttributeKind>(Tok.getString())
1671 .Case("system", AT_system)
1672 .Default(AT_unknown);
1673 switch (Attribute) {
1674 case AT_unknown:
1675 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1676 << Tok.getString();
1677 break;
1678
1679 case AT_system:
1680 Attrs.IsSystem = true;
1681 break;
1682 }
1683 consumeToken();
1684
1685 // Consume the ']'.
1686 if (!Tok.is(MMToken::RSquare)) {
1687 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1688 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1689 skipUntil(MMToken::RSquare);
1690 HadError = true;
1691 }
1692
1693 if (Tok.is(MMToken::RSquare))
1694 consumeToken();
1695 }
1696
1697 return HadError;
1698 }
1699
1700 /// \brief If there is a specific header search directory due the presence
1701 /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
getOverriddenHeaderSearchDir()1702 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1703 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1704 // If we have an umbrella directory, use that.
1705 if (Mod->hasUmbrellaDir())
1706 return Mod->getUmbrellaDir();
1707
1708 // If we have a framework directory, stop looking.
1709 if (Mod->IsFramework)
1710 return 0;
1711 }
1712
1713 return 0;
1714 }
1715
1716 /// \brief Parse a module map file.
1717 ///
1718 /// module-map-file:
1719 /// module-declaration*
parseModuleMapFile()1720 bool ModuleMapParser::parseModuleMapFile() {
1721 do {
1722 switch (Tok.Kind) {
1723 case MMToken::EndOfFile:
1724 return HadError;
1725
1726 case MMToken::ExplicitKeyword:
1727 case MMToken::ModuleKeyword:
1728 case MMToken::FrameworkKeyword:
1729 parseModuleDecl();
1730 break;
1731
1732 case MMToken::Comma:
1733 case MMToken::ExcludeKeyword:
1734 case MMToken::ExportKeyword:
1735 case MMToken::HeaderKeyword:
1736 case MMToken::Identifier:
1737 case MMToken::LBrace:
1738 case MMToken::LinkKeyword:
1739 case MMToken::LSquare:
1740 case MMToken::Period:
1741 case MMToken::RBrace:
1742 case MMToken::RSquare:
1743 case MMToken::RequiresKeyword:
1744 case MMToken::Star:
1745 case MMToken::StringLiteral:
1746 case MMToken::UmbrellaKeyword:
1747 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1748 HadError = true;
1749 consumeToken();
1750 break;
1751 }
1752 } while (true);
1753 }
1754
parseModuleMapFile(const FileEntry * File)1755 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1756 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1757 = ParsedModuleMap.find(File);
1758 if (Known != ParsedModuleMap.end())
1759 return Known->second;
1760
1761 assert(Target != 0 && "Missing target information");
1762 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1763 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1764 if (!Buffer)
1765 return ParsedModuleMap[File] = true;
1766
1767 // Parse this module map file.
1768 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1769 Diags->getClient()->BeginSourceFile(MMapLangOpts);
1770 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
1771 BuiltinIncludeDir);
1772 bool Result = Parser.parseModuleMapFile();
1773 Diags->getClient()->EndSourceFile();
1774 ParsedModuleMap[File] = Result;
1775 return Result;
1776 }
1777