1 //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the ModuleMap implementation, which describes the layout
11 // of a module as it relates to headers.
13 //===----------------------------------------------------------------------===//
14 #include "clang/Lex/ModuleMap.h"
15 #include "clang/Lex/Lexer.h"
16 #include "clang/Lex/LiteralSupport.h"
17 #include "clang/Lex/LexDiagnostic.h"
18 #include "clang/Basic/Diagnostic.h"
19 #include "clang/Basic/DiagnosticOptions.h"
20 #include "clang/Basic/FileManager.h"
21 #include "clang/Basic/TargetInfo.h"
22 #include "clang/Basic/TargetOptions.h"
23 #include "llvm/Support/Allocator.h"
24 #include "llvm/Support/FileSystem.h"
25 #include "llvm/Support/Host.h"
26 #include "llvm/Support/PathV2.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include "llvm/ADT/StringRef.h"
29 #include "llvm/ADT/StringSwitch.h"
31 using namespace clang;
34 ModuleMap::resolveExport(Module *Mod,
35 const Module::UnresolvedExportDecl &Unresolved,
37 // We may have just a wildcard.
38 if (Unresolved.Id.empty()) {
39 assert(Unresolved.Wildcard && "Invalid unresolved export");
40 return Module::ExportDecl(0, true);
43 // Find the starting module.
44 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
47 Diags->Report(Unresolved.Id[0].second,
48 diag::err_mmap_missing_module_unqualified)
49 << Unresolved.Id[0].first << Mod->getFullModuleName();
51 return Module::ExportDecl();
54 // Dig into the module path.
55 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
56 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
60 Diags->Report(Unresolved.Id[I].second,
61 diag::err_mmap_missing_module_qualified)
62 << Unresolved.Id[I].first << Context->getFullModuleName()
63 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
65 return Module::ExportDecl();
71 return Module::ExportDecl(Context, Unresolved.Wildcard);
74 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
75 const LangOptions &LangOpts, const TargetInfo *Target)
76 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0)
78 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
79 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
80 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
81 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
82 SourceMgr = new SourceManager(*Diags, FileMgr);
85 ModuleMap::~ModuleMap() {
86 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
95 void ModuleMap::setTarget(const TargetInfo &Target) {
96 assert((!this->Target || this->Target == &Target) &&
97 "Improper target override");
98 this->Target = &Target;
101 /// \brief "Sanitize" a filename so that it can be used as an identifier.
102 static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
103 SmallVectorImpl<char> &Buffer) {
107 // Check whether the filename is already an identifier; this is the common
109 bool isIdentifier = true;
110 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
111 if (isalpha(Name[I]) || Name[I] == '_' || (isdigit(Name[I]) && I > 0))
114 isIdentifier = false;
119 // If we don't already have something with the form of an identifier,
120 // create a buffer with the sanitized name.
122 if (isdigit(Name[0]))
123 Buffer.push_back('_');
124 Buffer.reserve(Buffer.size() + Name.size());
125 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
126 if (isalnum(Name[I]) || isspace(Name[I]))
127 Buffer.push_back(Name[I]);
129 Buffer.push_back('_');
132 Name = StringRef(Buffer.data(), Buffer.size());
135 while (llvm::StringSwitch<bool>(Name)
136 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
137 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
138 #include "clang/Basic/TokenKinds.def"
140 if (Name.data() != Buffer.data())
141 Buffer.append(Name.begin(), Name.end());
142 Buffer.push_back('_');
143 Name = StringRef(Buffer.data(), Buffer.size());
149 Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
150 HeadersMap::iterator Known = Headers.find(File);
151 if (Known != Headers.end()) {
152 // If a header is not available, don't report that it maps to anything.
153 if (!Known->second.isAvailable())
156 return Known->second.getModule();
159 const DirectoryEntry *Dir = File->getDir();
160 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
161 StringRef DirName = Dir->getName();
163 // Keep walking up the directory hierarchy, looking for a directory with
164 // an umbrella header.
166 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
167 = UmbrellaDirs.find(Dir);
168 if (KnownDir != UmbrellaDirs.end()) {
169 Module *Result = KnownDir->second;
171 // Search up the module stack until we find a module with an umbrella
173 Module *UmbrellaModule = Result;
174 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
175 UmbrellaModule = UmbrellaModule->Parent;
177 if (UmbrellaModule->InferSubmodules) {
178 // Infer submodules for each of the directories we found between
179 // the directory of the umbrella header and the directory where
180 // the actual header is located.
181 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
183 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
184 // Find or create the module that corresponds to this directory name.
185 SmallString<32> NameBuf;
186 StringRef Name = sanitizeFilenameAsIdentifier(
187 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
189 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
192 // Associate the module and the directory.
193 UmbrellaDirs[SkippedDirs[I-1]] = Result;
195 // If inferred submodules export everything they import, add a
196 // wildcard to the set of exports.
197 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
198 Result->Exports.push_back(Module::ExportDecl(0, true));
201 // Infer a submodule with the same name as this header file.
202 SmallString<32> NameBuf;
203 StringRef Name = sanitizeFilenameAsIdentifier(
204 llvm::sys::path::stem(File->getName()), NameBuf);
205 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
207 Result->TopHeaders.insert(File);
209 // If inferred submodules export everything they import, add a
210 // wildcard to the set of exports.
211 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
212 Result->Exports.push_back(Module::ExportDecl(0, true));
214 // Record each of the directories we stepped through as being part of
215 // the module we found, since the umbrella header covers them all.
216 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
217 UmbrellaDirs[SkippedDirs[I]] = Result;
220 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
222 // If a header corresponds to an unavailable module, don't report
223 // that it maps to anything.
224 if (!Result->isAvailable())
230 SkippedDirs.push_back(Dir);
232 // Retrieve our parent path.
233 DirName = llvm::sys::path::parent_path(DirName);
237 // Resolve the parent path to a directory entry.
238 Dir = SourceMgr->getFileManager().getDirectory(DirName);
244 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
245 HeadersMap::iterator Known = Headers.find(Header);
246 if (Known != Headers.end())
247 return !Known->second.isAvailable();
249 const DirectoryEntry *Dir = Header->getDir();
250 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
251 StringRef DirName = Dir->getName();
253 // Keep walking up the directory hierarchy, looking for a directory with
254 // an umbrella header.
256 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
257 = UmbrellaDirs.find(Dir);
258 if (KnownDir != UmbrellaDirs.end()) {
259 Module *Found = KnownDir->second;
260 if (!Found->isAvailable())
263 // Search up the module stack until we find a module with an umbrella
265 Module *UmbrellaModule = Found;
266 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
267 UmbrellaModule = UmbrellaModule->Parent;
269 if (UmbrellaModule->InferSubmodules) {
270 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
271 // Find or create the module that corresponds to this directory name.
272 SmallString<32> NameBuf;
273 StringRef Name = sanitizeFilenameAsIdentifier(
274 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
276 Found = lookupModuleQualified(Name, Found);
279 if (!Found->isAvailable())
283 // Infer a submodule with the same name as this header file.
284 SmallString<32> NameBuf;
285 StringRef Name = sanitizeFilenameAsIdentifier(
286 llvm::sys::path::stem(Header->getName()),
288 Found = lookupModuleQualified(Name, Found);
293 return !Found->isAvailable();
296 SkippedDirs.push_back(Dir);
298 // Retrieve our parent path.
299 DirName = llvm::sys::path::parent_path(DirName);
303 // Resolve the parent path to a directory entry.
304 Dir = SourceMgr->getFileManager().getDirectory(DirName);
310 Module *ModuleMap::findModule(StringRef Name) {
311 llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
312 if (Known != Modules.end())
313 return Known->getValue();
318 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
319 for(; Context; Context = Context->Parent) {
320 if (Module *Sub = lookupModuleQualified(Name, Context))
324 return findModule(Name);
327 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
329 return findModule(Name);
331 return Context->findSubmodule(Name);
334 std::pair<Module *, bool>
335 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
337 // Try to find an existing module with this name.
338 if (Module *Sub = lookupModuleQualified(Name, Parent))
339 return std::make_pair(Sub, false);
341 // Create a new module with this name.
342 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
345 Modules[Name] = Result;
346 return std::make_pair(Result, true);
349 bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
350 StringRef Name, bool &IsSystem) {
351 // Check whether we have already looked into the parent directory
353 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
354 inferred = InferredDirectories.find(ParentDir);
355 if (inferred == InferredDirectories.end())
358 if (!inferred->second.InferModules)
361 // We're allowed to infer for this directory, but make sure it's okay
362 // to infer this particular module.
363 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
364 inferred->second.ExcludedModules.end(),
365 Name) == inferred->second.ExcludedModules.end();
367 if (canInfer && inferred->second.InferSystemModules)
374 ModuleMap::inferFrameworkModule(StringRef ModuleName,
375 const DirectoryEntry *FrameworkDir,
378 // Check whether we've already found this module.
379 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
382 FileManager &FileMgr = SourceMgr->getFileManager();
384 // If the framework has a parent path from which we're allowed to infer
385 // a framework module, do so.
387 bool canInfer = false;
388 if (llvm::sys::path::has_parent_path(FrameworkDir->getName())) {
389 // Figure out the parent path.
390 StringRef Parent = llvm::sys::path::parent_path(FrameworkDir->getName());
391 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
392 // Check whether we have already looked into the parent directory
394 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
395 inferred = InferredDirectories.find(ParentDir);
396 if (inferred == InferredDirectories.end()) {
397 // We haven't looked here before. Load a module map, if there is
399 SmallString<128> ModMapPath = Parent;
400 llvm::sys::path::append(ModMapPath, "module.map");
401 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
402 parseModuleMapFile(ModMapFile);
403 inferred = InferredDirectories.find(ParentDir);
406 if (inferred == InferredDirectories.end())
407 inferred = InferredDirectories.insert(
408 std::make_pair(ParentDir, InferredDirectory())).first;
411 if (inferred->second.InferModules) {
412 // We're allowed to infer for this directory, but make sure it's okay
413 // to infer this particular module.
414 StringRef Name = llvm::sys::path::filename(FrameworkDir->getName());
415 canInfer = std::find(inferred->second.ExcludedModules.begin(),
416 inferred->second.ExcludedModules.end(),
417 Name) == inferred->second.ExcludedModules.end();
419 if (inferred->second.InferSystemModules)
425 // If we're not allowed to infer a framework module, don't.
431 // Look for an umbrella header.
432 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
433 llvm::sys::path::append(UmbrellaName, "Headers");
434 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
435 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
437 // FIXME: If there's no umbrella header, we could probably scan the
438 // framework to load *everything*. But, it's not clear that this is a good
443 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
444 /*IsFramework=*/true, /*IsExplicit=*/false);
446 Result->IsSystem = IsSystem;
449 Modules[ModuleName] = Result;
451 // umbrella header "umbrella-header-name"
452 Result->Umbrella = UmbrellaHeader;
453 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
454 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
457 Result->Exports.push_back(Module::ExportDecl(0, true));
459 // module * { export * }
460 Result->InferSubmodules = true;
461 Result->InferExportWildcard = true;
463 // Look for subframeworks.
465 SmallString<128> SubframeworksDirName
466 = StringRef(FrameworkDir->getName());
467 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
468 SmallString<128> SubframeworksDirNameNative;
469 llvm::sys::path::native(SubframeworksDirName.str(),
470 SubframeworksDirNameNative);
471 for (llvm::sys::fs::directory_iterator
472 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
473 Dir != DirEnd && !EC; Dir.increment(EC)) {
474 if (!StringRef(Dir->path()).endswith(".framework"))
477 if (const DirectoryEntry *SubframeworkDir
478 = FileMgr.getDirectory(Dir->path())) {
479 // Note: as an egregious but useful hack, we use the real path here and
480 // check whether it is actually a subdirectory of the parent directory.
481 // This will not be the case if the 'subframework' is actually a symlink
482 // out to a top-level framework.
484 char RealSubframeworkDirName[PATH_MAX];
485 if (realpath(Dir->path().c_str(), RealSubframeworkDirName)) {
486 StringRef SubframeworkDirName = RealSubframeworkDirName;
488 bool FoundParent = false;
490 // Get the parent directory name.
492 = llvm::sys::path::parent_path(SubframeworkDirName);
493 if (SubframeworkDirName.empty())
496 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
507 // FIXME: Do we want to warn about subframeworks without umbrella headers?
508 SmallString<32> NameBuf;
509 inferFrameworkModule(sanitizeFilenameAsIdentifier(
510 llvm::sys::path::stem(Dir->path()), NameBuf),
511 SubframeworkDir, IsSystem, Result);
518 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
519 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
520 Mod->Umbrella = UmbrellaHeader;
521 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
524 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
525 Mod->Umbrella = UmbrellaDir;
526 UmbrellaDirs[UmbrellaDir] = Mod;
529 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
532 Mod->ExcludedHeaders.push_back(Header);
534 Mod->Headers.push_back(Header);
535 Headers[Header] = KnownHeader(Mod, Excluded);
539 ModuleMap::getContainingModuleMapFile(Module *Module) {
540 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
543 return SourceMgr->getFileEntryForID(
544 SourceMgr->getFileID(Module->DefinitionLoc));
547 void ModuleMap::dump() {
548 llvm::errs() << "Modules:";
549 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
550 MEnd = Modules.end();
552 M->getValue()->print(llvm::errs(), 2);
554 llvm::errs() << "Headers:";
555 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
557 llvm::errs() << " \"" << H->first->getName() << "\" -> "
558 << H->second.getModule()->getFullModuleName() << "\n";
562 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
563 bool HadError = false;
564 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
565 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
567 if (Export.getPointer() || Export.getInt())
568 Mod->Exports.push_back(Export);
572 Mod->UnresolvedExports.clear();
576 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
580 // Use the expansion location to determine which module we're in.
581 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
582 if (!ExpansionLoc.isFileID())
586 const SourceManager &SrcMgr = Loc.getManager();
587 FileID ExpansionFileID = ExpansionLoc.getFileID();
589 while (const FileEntry *ExpansionFile
590 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
591 // Find the module that owns this header (if any).
592 if (Module *Mod = findModuleForHeader(ExpansionFile))
595 // No module owns this header, so look up the inclusion chain to see if
596 // any included header has an associated module.
597 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
598 if (IncludeLoc.isInvalid())
601 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
607 //----------------------------------------------------------------------------//
608 // Module map file parser
609 //----------------------------------------------------------------------------//
612 /// \brief A token in a module map file.
636 unsigned StringLength;
637 const char *StringData;
646 bool is(TokenKind K) const { return Kind == K; }
648 SourceLocation getLocation() const {
649 return SourceLocation::getFromRawEncoding(Location);
652 StringRef getString() const {
653 return StringRef(StringData, StringLength);
657 /// \brief The set of attributes that can be attached to a module.
659 Attributes() : IsSystem() { }
661 /// \brief Whether this is a system module.
662 unsigned IsSystem : 1;
666 class ModuleMapParser {
668 SourceManager &SourceMgr;
670 /// \brief Default target information, used only for string literal
672 const TargetInfo *Target;
674 DiagnosticsEngine &Diags;
677 /// \brief The directory that this module map resides in.
678 const DirectoryEntry *Directory;
680 /// \brief The directory containing Clang-supplied headers.
681 const DirectoryEntry *BuiltinIncludeDir;
683 /// \brief Whether an error occurred.
686 /// \brief Stores string data for the various string literals referenced
688 llvm::BumpPtrAllocator StringData;
690 /// \brief The current token.
693 /// \brief The active module.
694 Module *ActiveModule;
696 /// \brief Consume the current token and return its location.
697 SourceLocation consumeToken();
699 /// \brief Skip tokens until we reach the a token with the given kind
700 /// (or the end of the file).
701 void skipUntil(MMToken::TokenKind K);
703 typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
705 bool parseModuleId(ModuleId &Id);
706 void parseModuleDecl();
707 void parseRequiresDecl();
708 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
709 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
710 void parseExportDecl();
711 void parseInferredModuleDecl(bool Framework, bool Explicit);
712 bool parseOptionalAttributes(Attributes &Attrs);
714 const DirectoryEntry *getOverriddenHeaderSearchDir();
717 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
718 const TargetInfo *Target,
719 DiagnosticsEngine &Diags,
721 const DirectoryEntry *Directory,
722 const DirectoryEntry *BuiltinIncludeDir)
723 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
724 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
725 HadError(false), ActiveModule(0)
731 bool parseModuleMapFile();
735 SourceLocation ModuleMapParser::consumeToken() {
737 SourceLocation Result = Tok.getLocation();
741 L.LexFromRawLexer(LToken);
742 Tok.Location = LToken.getLocation().getRawEncoding();
743 switch (LToken.getKind()) {
744 case tok::raw_identifier:
745 Tok.StringData = LToken.getRawIdentifierData();
746 Tok.StringLength = LToken.getLength();
747 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
748 .Case("header", MMToken::HeaderKeyword)
749 .Case("exclude", MMToken::ExcludeKeyword)
750 .Case("explicit", MMToken::ExplicitKeyword)
751 .Case("export", MMToken::ExportKeyword)
752 .Case("framework", MMToken::FrameworkKeyword)
753 .Case("module", MMToken::ModuleKeyword)
754 .Case("requires", MMToken::RequiresKeyword)
755 .Case("umbrella", MMToken::UmbrellaKeyword)
756 .Default(MMToken::Identifier);
760 Tok.Kind = MMToken::Comma;
764 Tok.Kind = MMToken::EndOfFile;
768 Tok.Kind = MMToken::LBrace;
772 Tok.Kind = MMToken::LSquare;
776 Tok.Kind = MMToken::Period;
780 Tok.Kind = MMToken::RBrace;
784 Tok.Kind = MMToken::RSquare;
788 Tok.Kind = MMToken::Star;
791 case tok::string_literal: {
792 if (LToken.hasUDSuffix()) {
793 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
798 // Parse the string literal.
799 LangOptions LangOpts;
800 StringLiteralParser StringLiteral(<oken, 1, SourceMgr, LangOpts, *Target);
801 if (StringLiteral.hadError)
804 // Copy the string literal into our string data allocator.
805 unsigned Length = StringLiteral.GetStringLength();
806 char *Saved = StringData.Allocate<char>(Length + 1);
807 memcpy(Saved, StringLiteral.GetString().data(), Length);
811 Tok.Kind = MMToken::StringLiteral;
812 Tok.StringData = Saved;
813 Tok.StringLength = Length;
821 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
829 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
830 unsigned braceDepth = 0;
831 unsigned squareDepth = 0;
834 case MMToken::EndOfFile:
837 case MMToken::LBrace:
838 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
844 case MMToken::LSquare:
845 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
851 case MMToken::RBrace:
858 case MMToken::RSquare:
866 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
875 /// \brief Parse a module-id.
879 /// identifier '.' module-id
881 /// \returns true if an error occurred, false otherwise.
882 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
885 if (Tok.is(MMToken::Identifier)) {
886 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
889 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
893 if (!Tok.is(MMToken::Period))
903 /// \brief Enumerates the known attributes.
905 /// \brief An unknown attribute.
907 /// \brief The 'system' attribute.
912 /// \brief Parse a module declaration.
914 /// module-declaration:
915 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
916 /// { module-member* }
919 /// requires-declaration
920 /// header-declaration
921 /// submodule-declaration
922 /// export-declaration
924 /// submodule-declaration:
925 /// module-declaration
926 /// inferred-submodule-declaration
927 void ModuleMapParser::parseModuleDecl() {
928 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
929 Tok.is(MMToken::FrameworkKeyword));
930 // Parse 'explicit' or 'framework' keyword, if present.
931 SourceLocation ExplicitLoc;
932 bool Explicit = false;
933 bool Framework = false;
935 // Parse 'explicit' keyword, if present.
936 if (Tok.is(MMToken::ExplicitKeyword)) {
937 ExplicitLoc = consumeToken();
941 // Parse 'framework' keyword, if present.
942 if (Tok.is(MMToken::FrameworkKeyword)) {
947 // Parse 'module' keyword.
948 if (!Tok.is(MMToken::ModuleKeyword)) {
949 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
954 consumeToken(); // 'module' keyword
956 // If we have a wildcard for the module name, this is an inferred submodule.
958 if (Tok.is(MMToken::Star))
959 return parseInferredModuleDecl(Framework, Explicit);
961 // Parse the module name.
963 if (parseModuleId(Id)) {
970 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
971 << SourceRange(Id.front().second, Id.back().second);
976 } else if (Id.size() == 1 && Explicit) {
977 // Top-level modules can't be explicit.
978 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
980 ExplicitLoc = SourceLocation();
984 Module *PreviousActiveModule = ActiveModule;
986 // This module map defines a submodule. Go find the module of which it
989 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
990 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
996 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
997 << Id[I].first << ActiveModule->getTopLevelModule();
999 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1006 StringRef ModuleName = Id.back().first;
1007 SourceLocation ModuleNameLoc = Id.back().second;
1009 // Parse the optional attribute list.
1011 parseOptionalAttributes(Attrs);
1013 // Parse the opening brace.
1014 if (!Tok.is(MMToken::LBrace)) {
1015 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1020 SourceLocation LBraceLoc = consumeToken();
1022 // Determine whether this (sub)module has already been defined.
1023 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1024 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1025 // Skip the module definition.
1026 skipUntil(MMToken::RBrace);
1027 if (Tok.is(MMToken::RBrace))
1030 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1031 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1037 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1039 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1041 // Skip the module definition.
1042 skipUntil(MMToken::RBrace);
1043 if (Tok.is(MMToken::RBrace))
1050 // Start defining this module.
1051 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1053 ActiveModule->DefinitionLoc = ModuleNameLoc;
1055 ActiveModule->IsSystem = true;
1060 case MMToken::EndOfFile:
1061 case MMToken::RBrace:
1065 case MMToken::ExplicitKeyword:
1066 case MMToken::FrameworkKeyword:
1067 case MMToken::ModuleKeyword:
1071 case MMToken::ExportKeyword:
1075 case MMToken::RequiresKeyword:
1076 parseRequiresDecl();
1079 case MMToken::UmbrellaKeyword: {
1080 SourceLocation UmbrellaLoc = consumeToken();
1081 if (Tok.is(MMToken::HeaderKeyword))
1082 parseHeaderDecl(UmbrellaLoc, SourceLocation());
1084 parseUmbrellaDirDecl(UmbrellaLoc);
1088 case MMToken::ExcludeKeyword: {
1089 SourceLocation ExcludeLoc = consumeToken();
1090 if (Tok.is(MMToken::HeaderKeyword)) {
1091 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1093 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1099 case MMToken::HeaderKeyword:
1100 parseHeaderDecl(SourceLocation(), SourceLocation());
1104 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1110 if (Tok.is(MMToken::RBrace))
1113 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1114 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1118 // We're done parsing this module. Pop back to the previous module.
1119 ActiveModule = PreviousActiveModule;
1122 /// \brief Parse a requires declaration.
1124 /// requires-declaration:
1125 /// 'requires' feature-list
1128 /// identifier ',' feature-list
1130 void ModuleMapParser::parseRequiresDecl() {
1131 assert(Tok.is(MMToken::RequiresKeyword));
1133 // Parse 'requires' keyword.
1136 // Parse the feature-list.
1138 if (!Tok.is(MMToken::Identifier)) {
1139 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1144 // Consume the feature name.
1145 std::string Feature = Tok.getString();
1148 // Add this feature.
1149 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
1151 if (!Tok.is(MMToken::Comma))
1154 // Consume the comma.
1159 /// \brief Append to \p Paths the set of paths needed to get to the
1160 /// subframework in which the given module lives.
1161 static void appendSubframeworkPaths(Module *Mod,
1162 llvm::SmallVectorImpl<char> &Path) {
1163 // Collect the framework names from the given module to the top-level module.
1164 llvm::SmallVector<StringRef, 2> Paths;
1165 for (; Mod; Mod = Mod->Parent) {
1166 if (Mod->IsFramework)
1167 Paths.push_back(Mod->Name);
1173 // Add Frameworks/Name.framework for each subframework.
1174 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1175 llvm::sys::path::append(Path, "Frameworks");
1176 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1180 /// \brief Determine whether the given file name is the name of a builtin
1181 /// header, supplied by Clang to replace, override, or augment existing system
1183 static bool isBuiltinHeader(StringRef FileName) {
1184 return llvm::StringSwitch<bool>(FileName)
1185 .Case("float.h", true)
1186 .Case("iso646.h", true)
1187 .Case("limits.h", true)
1188 .Case("stdalign.h", true)
1189 .Case("stdarg.h", true)
1190 .Case("stdbool.h", true)
1191 .Case("stddef.h", true)
1192 .Case("stdint.h", true)
1193 .Case("tgmath.h", true)
1194 .Case("unwind.h", true)
1198 /// \brief Parse a header declaration.
1200 /// header-declaration:
1201 /// 'umbrella'[opt] 'header' string-literal
1202 /// 'exclude'[opt] 'header' string-literal
1203 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1204 SourceLocation ExcludeLoc) {
1205 assert(Tok.is(MMToken::HeaderKeyword));
1208 bool Umbrella = UmbrellaLoc.isValid();
1209 bool Exclude = ExcludeLoc.isValid();
1210 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
1211 // Parse the header name.
1212 if (!Tok.is(MMToken::StringLiteral)) {
1213 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1218 std::string FileName = Tok.getString();
1219 SourceLocation FileNameLoc = consumeToken();
1221 // Check whether we already have an umbrella.
1222 if (Umbrella && ActiveModule->Umbrella) {
1223 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1224 << ActiveModule->getFullModuleName();
1229 // Look for this file.
1230 const FileEntry *File = 0;
1231 const FileEntry *BuiltinFile = 0;
1232 SmallString<128> PathName;
1233 if (llvm::sys::path::is_absolute(FileName)) {
1234 PathName = FileName;
1235 File = SourceMgr.getFileManager().getFile(PathName);
1236 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1237 PathName = Dir->getName();
1238 llvm::sys::path::append(PathName, FileName);
1239 File = SourceMgr.getFileManager().getFile(PathName);
1241 // Search for the header file within the search directory.
1242 PathName = Directory->getName();
1243 unsigned PathLength = PathName.size();
1245 if (ActiveModule->isPartOfFramework()) {
1246 appendSubframeworkPaths(ActiveModule, PathName);
1248 // Check whether this file is in the public headers.
1249 llvm::sys::path::append(PathName, "Headers");
1250 llvm::sys::path::append(PathName, FileName);
1251 File = SourceMgr.getFileManager().getFile(PathName);
1254 // Check whether this file is in the private headers.
1255 PathName.resize(PathLength);
1256 llvm::sys::path::append(PathName, "PrivateHeaders");
1257 llvm::sys::path::append(PathName, FileName);
1258 File = SourceMgr.getFileManager().getFile(PathName);
1261 // Lookup for normal headers.
1262 llvm::sys::path::append(PathName, FileName);
1263 File = SourceMgr.getFileManager().getFile(PathName);
1265 // If this is a system module with a top-level header, this header
1266 // may have a counterpart (or replacement) in the set of headers
1267 // supplied by Clang. Find that builtin header.
1268 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1269 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
1270 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1271 llvm::sys::path::append(BuiltinPathName, FileName);
1272 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1274 // If Clang supplies this header but the underlying system does not,
1275 // just silently swap in our builtin version. Otherwise, we'll end
1276 // up adding both (later).
1277 if (!File && BuiltinFile) {
1285 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1286 // Come up with a lazy way to do this.
1288 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
1289 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
1290 << FileName << OwningModule.getModule()->getFullModuleName();
1292 } else if (Umbrella) {
1293 const DirectoryEntry *UmbrellaDir = File->getDir();
1294 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1295 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1296 << UmbrellaModule->getFullModuleName();
1299 // Record this umbrella header.
1300 Map.setUmbrellaHeader(ActiveModule, File);
1303 // Record this header.
1304 Map.addHeader(ActiveModule, File, Exclude);
1306 // If there is a builtin counterpart to this file, add it now.
1308 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
1311 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1312 << Umbrella << FileName;
1317 /// \brief Parse an umbrella directory declaration.
1319 /// umbrella-dir-declaration:
1320 /// umbrella string-literal
1321 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1322 // Parse the directory name.
1323 if (!Tok.is(MMToken::StringLiteral)) {
1324 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1330 std::string DirName = Tok.getString();
1331 SourceLocation DirNameLoc = consumeToken();
1333 // Check whether we already have an umbrella.
1334 if (ActiveModule->Umbrella) {
1335 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1336 << ActiveModule->getFullModuleName();
1341 // Look for this file.
1342 const DirectoryEntry *Dir = 0;
1343 if (llvm::sys::path::is_absolute(DirName))
1344 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1346 SmallString<128> PathName;
1347 PathName = Directory->getName();
1348 llvm::sys::path::append(PathName, DirName);
1349 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1353 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1359 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1360 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1361 << OwningModule->getFullModuleName();
1366 // Record this umbrella directory.
1367 Map.setUmbrellaDir(ActiveModule, Dir);
1370 /// \brief Parse a module export declaration.
1372 /// export-declaration:
1373 /// 'export' wildcard-module-id
1375 /// wildcard-module-id:
1378 /// identifier '.' wildcard-module-id
1379 void ModuleMapParser::parseExportDecl() {
1380 assert(Tok.is(MMToken::ExportKeyword));
1381 SourceLocation ExportLoc = consumeToken();
1383 // Parse the module-id with an optional wildcard at the end.
1384 ModuleId ParsedModuleId;
1385 bool Wildcard = false;
1387 if (Tok.is(MMToken::Identifier)) {
1388 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1389 Tok.getLocation()));
1392 if (Tok.is(MMToken::Period)) {
1400 if(Tok.is(MMToken::Star)) {
1406 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1411 Module::UnresolvedExportDecl Unresolved = {
1412 ExportLoc, ParsedModuleId, Wildcard
1414 ActiveModule->UnresolvedExports.push_back(Unresolved);
1417 /// \brief Parse an inferried module declaration (wildcard modules).
1419 /// module-declaration:
1420 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1421 /// { inferred-module-member* }
1423 /// inferred-module-member:
1425 /// 'exclude' identifier
1426 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
1427 assert(Tok.is(MMToken::Star));
1428 SourceLocation StarLoc = consumeToken();
1429 bool Failed = false;
1431 // Inferred modules must be submodules.
1432 if (!ActiveModule && !Framework) {
1433 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1438 // Inferred modules must have umbrella directories.
1439 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1440 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1444 // Check for redefinition of an inferred module.
1445 if (!Failed && ActiveModule->InferSubmodules) {
1446 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1447 if (ActiveModule->InferredSubmoduleLoc.isValid())
1448 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1449 diag::note_mmap_prev_definition);
1453 // Check for the 'framework' keyword, which is not permitted here.
1455 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1458 } else if (Explicit) {
1459 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1463 // If there were any problems with this inferred submodule, skip its body.
1465 if (Tok.is(MMToken::LBrace)) {
1467 skipUntil(MMToken::RBrace);
1468 if (Tok.is(MMToken::RBrace))
1475 // Parse optional attributes.
1477 parseOptionalAttributes(Attrs);
1480 // Note that we have an inferred submodule.
1481 ActiveModule->InferSubmodules = true;
1482 ActiveModule->InferredSubmoduleLoc = StarLoc;
1483 ActiveModule->InferExplicitSubmodules = Explicit;
1485 // We'll be inferring framework modules for this directory.
1486 Map.InferredDirectories[Directory].InferModules = true;
1487 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1490 // Parse the opening brace.
1491 if (!Tok.is(MMToken::LBrace)) {
1492 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1496 SourceLocation LBraceLoc = consumeToken();
1498 // Parse the body of the inferred submodule.
1502 case MMToken::EndOfFile:
1503 case MMToken::RBrace:
1507 case MMToken::ExcludeKeyword: {
1509 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1510 << (ActiveModule != 0);
1516 if (!Tok.is(MMToken::Identifier)) {
1517 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1521 Map.InferredDirectories[Directory].ExcludedModules
1522 .push_back(Tok.getString());
1527 case MMToken::ExportKeyword:
1528 if (!ActiveModule) {
1529 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1530 << (ActiveModule != 0);
1536 if (Tok.is(MMToken::Star))
1537 ActiveModule->InferExportWildcard = true;
1539 Diags.Report(Tok.getLocation(),
1540 diag::err_mmap_expected_export_wildcard);
1544 case MMToken::ExplicitKeyword:
1545 case MMToken::ModuleKeyword:
1546 case MMToken::HeaderKeyword:
1547 case MMToken::UmbrellaKeyword:
1549 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1550 << (ActiveModule != 0);
1556 if (Tok.is(MMToken::RBrace))
1559 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1560 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1565 /// \brief Parse optional attributes.
1568 /// attribute attributes
1574 /// \param Attrs Will be filled in with the parsed attributes.
1576 /// \returns true if an error occurred, false otherwise.
1577 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
1578 bool HadError = false;
1580 while (Tok.is(MMToken::LSquare)) {
1582 SourceLocation LSquareLoc = consumeToken();
1584 // Check whether we have an attribute name here.
1585 if (!Tok.is(MMToken::Identifier)) {
1586 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1587 skipUntil(MMToken::RSquare);
1588 if (Tok.is(MMToken::RSquare))
1593 // Decode the attribute name.
1594 AttributeKind Attribute
1595 = llvm::StringSwitch<AttributeKind>(Tok.getString())
1596 .Case("system", AT_system)
1597 .Default(AT_unknown);
1598 switch (Attribute) {
1600 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1605 Attrs.IsSystem = true;
1611 if (!Tok.is(MMToken::RSquare)) {
1612 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1613 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1614 skipUntil(MMToken::RSquare);
1618 if (Tok.is(MMToken::RSquare))
1625 /// \brief If there is a specific header search directory due the presence
1626 /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1627 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1628 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1629 // If we have an umbrella directory, use that.
1630 if (Mod->hasUmbrellaDir())
1631 return Mod->getUmbrellaDir();
1633 // If we have a framework directory, stop looking.
1634 if (Mod->IsFramework)
1641 /// \brief Parse a module map file.
1643 /// module-map-file:
1644 /// module-declaration*
1645 bool ModuleMapParser::parseModuleMapFile() {
1648 case MMToken::EndOfFile:
1651 case MMToken::ExplicitKeyword:
1652 case MMToken::ModuleKeyword:
1653 case MMToken::FrameworkKeyword:
1657 case MMToken::Comma:
1658 case MMToken::ExcludeKeyword:
1659 case MMToken::ExportKeyword:
1660 case MMToken::HeaderKeyword:
1661 case MMToken::Identifier:
1662 case MMToken::LBrace:
1663 case MMToken::LSquare:
1664 case MMToken::Period:
1665 case MMToken::RBrace:
1666 case MMToken::RSquare:
1667 case MMToken::RequiresKeyword:
1669 case MMToken::StringLiteral:
1670 case MMToken::UmbrellaKeyword:
1671 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1679 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1680 assert(Target != 0 && "Missing target information");
1681 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1682 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1686 // Parse this module map file.
1687 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1688 Diags->getClient()->BeginSourceFile(MMapLangOpts);
1689 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
1691 bool Result = Parser.parseModuleMapFile();
1692 Diags->getClient()->EndSourceFile();