xref: /llvm-project/clang/lib/Lex/ModuleMap.cpp (revision ef42154c17ccdd7838aa46880ea3d07f5516b886)
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/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/FileManager.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Basic/TargetOptions.h"
22 #include "llvm/Support/Allocator.h"
23 #include "llvm/Support/Host.h"
24 #include "llvm/Support/PathV2.h"
25 #include "llvm/Support/raw_ostream.h"
26 #include "llvm/ADT/StringRef.h"
27 #include "llvm/ADT/StringSwitch.h"
28 using namespace clang;
29 
30 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC) {
31   llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
32   Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>(
33             new DiagnosticsEngine(DiagIDs));
34   Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
35   SourceMgr = new SourceManager(*Diags, FileMgr);
36 }
37 
38 ModuleMap::~ModuleMap() {
39   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
40                                         IEnd = Modules.end();
41        I != IEnd; ++I) {
42     delete I->getValue();
43   }
44 
45   delete SourceMgr;
46 }
47 
48 Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
49   llvm::DenseMap<const FileEntry *, Module *>::iterator Known
50     = Headers.find(File);
51   if (Known != Headers.end())
52     return Known->second;
53 
54   const DirectoryEntry *Dir = File->getDir();
55   llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
56     = UmbrellaDirs.find(Dir);
57   if (KnownDir != UmbrellaDirs.end())
58     return KnownDir->second;
59 
60   // Walk up the directory hierarchy looking for umbrella headers.
61   llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
62   StringRef DirName = Dir->getName();
63   do {
64     // Retrieve our parent path.
65     DirName = llvm::sys::path::parent_path(DirName);
66     if (DirName.empty())
67       break;
68 
69     // Resolve the parent path to a directory entry.
70     Dir = SourceMgr->getFileManager().getDirectory(DirName);
71     if (!Dir)
72       break;
73 
74     KnownDir = UmbrellaDirs.find(Dir);
75     if (KnownDir != UmbrellaDirs.end()) {
76       Module *Result = KnownDir->second;
77 
78       // Record each of the directories we stepped through as being part of
79       // the module we found, since the umbrella header covers them all.
80       for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
81         UmbrellaDirs[SkippedDirs[I]] = Result;
82 
83       return Result;
84     }
85 
86     SkippedDirs.push_back(Dir);
87   } while (true);
88 
89   return 0;
90 }
91 
92 Module *ModuleMap::findModule(StringRef Name) {
93   llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
94   if (Known != Modules.end())
95     return Known->getValue();
96 
97   return 0;
98 }
99 
100 std::pair<Module *, bool>
101 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
102                               bool IsExplicit) {
103   // Try to find an existing module with this name.
104   if (Module *Found = Parent? Parent->SubModules[Name] : Modules[Name])
105     return std::make_pair(Found, false);
106 
107   // Create a new module with this name.
108   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
109                               IsExplicit);
110   if (Parent)
111     Parent->SubModules[Name] = Result;
112   else
113     Modules[Name] = Result;
114   return std::make_pair(Result, true);
115 }
116 
117 Module *
118 ModuleMap::inferFrameworkModule(StringRef ModuleName,
119                                 const DirectoryEntry *FrameworkDir) {
120   // Check whether we've already found this module.
121   if (Module *Module = findModule(ModuleName))
122     return Module;
123 
124   // Look for an umbrella header.
125   llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
126   llvm::sys::path::append(UmbrellaName, "Headers");
127   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
128   const FileEntry *UmbrellaHeader
129     = SourceMgr->getFileManager().getFile(UmbrellaName);
130 
131   // FIXME: If there's no umbrella header, we could probably scan the
132   // framework to load *everything*. But, it's not clear that this is a good
133   // idea.
134   if (!UmbrellaHeader)
135     return 0;
136 
137   Module *Result = new Module(ModuleName, SourceLocation(),
138                               /*IsFramework=*/true);
139   Result->UmbrellaHeader = UmbrellaHeader;
140   Headers[UmbrellaHeader] = Result;
141   UmbrellaDirs[FrameworkDir] = Result;
142   Modules[ModuleName] = Result;
143   return Result;
144 }
145 
146 const FileEntry *
147 ModuleMap::getContainingModuleMapFile(Module *Module) {
148   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
149     return 0;
150 
151   return SourceMgr->getFileEntryForID(
152            SourceMgr->getFileID(Module->DefinitionLoc));
153 }
154 
155 void ModuleMap::dump() {
156   llvm::errs() << "Modules:";
157   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
158                                         MEnd = Modules.end();
159        M != MEnd; ++M)
160     M->getValue()->print(llvm::errs(), 2);
161 
162   llvm::errs() << "Headers:";
163   for (llvm::DenseMap<const FileEntry *, Module *>::iterator
164             H = Headers.begin(),
165          HEnd = Headers.end();
166        H != HEnd; ++H) {
167     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
168                  << H->second->getFullModuleName() << "\n";
169   }
170 }
171 
172 //----------------------------------------------------------------------------//
173 // Module map file parser
174 //----------------------------------------------------------------------------//
175 
176 namespace clang {
177   /// \brief A token in a module map file.
178   struct MMToken {
179     enum TokenKind {
180       EndOfFile,
181       HeaderKeyword,
182       Identifier,
183       ExplicitKeyword,
184       FrameworkKeyword,
185       ModuleKeyword,
186       UmbrellaKeyword,
187       StringLiteral,
188       LBrace,
189       RBrace
190     } Kind;
191 
192     unsigned Location;
193     unsigned StringLength;
194     const char *StringData;
195 
196     void clear() {
197       Kind = EndOfFile;
198       Location = 0;
199       StringLength = 0;
200       StringData = 0;
201     }
202 
203     bool is(TokenKind K) const { return Kind == K; }
204 
205     SourceLocation getLocation() const {
206       return SourceLocation::getFromRawEncoding(Location);
207     }
208 
209     StringRef getString() const {
210       return StringRef(StringData, StringLength);
211     }
212   };
213 
214   class ModuleMapParser {
215     Lexer &L;
216     SourceManager &SourceMgr;
217     DiagnosticsEngine &Diags;
218     ModuleMap &Map;
219 
220     /// \brief The directory that this module map resides in.
221     const DirectoryEntry *Directory;
222 
223     /// \brief Whether an error occurred.
224     bool HadError;
225 
226     /// \brief Default target information, used only for string literal
227     /// parsing.
228     TargetInfo *Target;
229 
230     /// \brief Stores string data for the various string literals referenced
231     /// during parsing.
232     llvm::BumpPtrAllocator StringData;
233 
234     /// \brief The current token.
235     MMToken Tok;
236 
237     /// \brief The active module.
238     Module *ActiveModule;
239 
240     /// \brief Consume the current token and return its location.
241     SourceLocation consumeToken();
242 
243     /// \brief Skip tokens until we reach the a token with the given kind
244     /// (or the end of the file).
245     void skipUntil(MMToken::TokenKind K);
246 
247     void parseModuleDecl();
248     void parseUmbrellaDecl();
249     void parseHeaderDecl();
250 
251   public:
252     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
253                              DiagnosticsEngine &Diags,
254                              ModuleMap &Map,
255                              const DirectoryEntry *Directory)
256       : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
257         Directory(Directory), HadError(false), ActiveModule(0)
258     {
259       TargetOptions TargetOpts;
260       TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
261       Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
262 
263       Tok.clear();
264       consumeToken();
265     }
266 
267     bool parseModuleMapFile();
268   };
269 }
270 
271 SourceLocation ModuleMapParser::consumeToken() {
272 retry:
273   SourceLocation Result = Tok.getLocation();
274   Tok.clear();
275 
276   Token LToken;
277   L.LexFromRawLexer(LToken);
278   Tok.Location = LToken.getLocation().getRawEncoding();
279   switch (LToken.getKind()) {
280   case tok::raw_identifier:
281     Tok.StringData = LToken.getRawIdentifierData();
282     Tok.StringLength = LToken.getLength();
283     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
284                  .Case("header", MMToken::HeaderKeyword)
285                  .Case("explicit", MMToken::ExplicitKeyword)
286                  .Case("framework", MMToken::FrameworkKeyword)
287                  .Case("module", MMToken::ModuleKeyword)
288                  .Case("umbrella", MMToken::UmbrellaKeyword)
289                  .Default(MMToken::Identifier);
290     break;
291 
292   case tok::eof:
293     Tok.Kind = MMToken::EndOfFile;
294     break;
295 
296   case tok::l_brace:
297     Tok.Kind = MMToken::LBrace;
298     break;
299 
300   case tok::r_brace:
301     Tok.Kind = MMToken::RBrace;
302     break;
303 
304   case tok::string_literal: {
305     // Parse the string literal.
306     LangOptions LangOpts;
307     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
308     if (StringLiteral.hadError)
309       goto retry;
310 
311     // Copy the string literal into our string data allocator.
312     unsigned Length = StringLiteral.GetStringLength();
313     char *Saved = StringData.Allocate<char>(Length + 1);
314     memcpy(Saved, StringLiteral.GetString().data(), Length);
315     Saved[Length] = 0;
316 
317     // Form the token.
318     Tok.Kind = MMToken::StringLiteral;
319     Tok.StringData = Saved;
320     Tok.StringLength = Length;
321     break;
322   }
323 
324   case tok::comment:
325     goto retry;
326 
327   default:
328     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
329     HadError = true;
330     goto retry;
331   }
332 
333   return Result;
334 }
335 
336 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
337   unsigned braceDepth = 0;
338   do {
339     switch (Tok.Kind) {
340     case MMToken::EndOfFile:
341       return;
342 
343     case MMToken::LBrace:
344       if (Tok.is(K) && braceDepth == 0)
345         return;
346 
347       ++braceDepth;
348       break;
349 
350     case MMToken::RBrace:
351       if (braceDepth > 0)
352         --braceDepth;
353       else if (Tok.is(K))
354         return;
355       break;
356 
357     default:
358       if (braceDepth == 0 && Tok.is(K))
359         return;
360       break;
361     }
362 
363    consumeToken();
364   } while (true);
365 }
366 
367 /// \brief Parse a module declaration.
368 ///
369 ///   module-declaration:
370 ///     'framework'[opt] 'module' identifier { module-member* }
371 ///
372 ///   module-member:
373 ///     umbrella-declaration
374 ///     header-declaration
375 ///     'explicit'[opt] module-declaration
376 void ModuleMapParser::parseModuleDecl() {
377   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
378          Tok.is(MMToken::FrameworkKeyword));
379 
380   // Parse 'framework' or 'explicit' keyword, if present.
381   bool Framework = false;
382   bool Explicit = false;
383 
384   if (Tok.is(MMToken::FrameworkKeyword)) {
385     consumeToken();
386     Framework = true;
387   }
388   // Parse 'explicit' keyword, if present.
389   else if (Tok.is(MMToken::ExplicitKeyword)) {
390     consumeToken();
391     Explicit = true;
392   }
393 
394   // Parse 'module' keyword.
395   if (!Tok.is(MMToken::ModuleKeyword)) {
396     Diags.Report(Tok.getLocation(),
397                  diag::err_mmap_expected_module_after_explicit);
398     consumeToken();
399     HadError = true;
400     return;
401   }
402   consumeToken(); // 'module' keyword
403 
404   // Parse the module name.
405   if (!Tok.is(MMToken::Identifier)) {
406     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
407     HadError = true;
408     return;
409   }
410   StringRef ModuleName = Tok.getString();
411   SourceLocation ModuleNameLoc = consumeToken();
412 
413   // Parse the opening brace.
414   if (!Tok.is(MMToken::LBrace)) {
415     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
416       << ModuleName;
417     HadError = true;
418     return;
419   }
420   SourceLocation LBraceLoc = consumeToken();
421 
422   // Determine whether this (sub)module has already been defined.
423   llvm::StringMap<Module *> &ModuleSpace
424     = ActiveModule? ActiveModule->SubModules : Map.Modules;
425   llvm::StringMap<Module *>::iterator ExistingModule
426     = ModuleSpace.find(ModuleName);
427   if (ExistingModule != ModuleSpace.end()) {
428     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
429       << ModuleName;
430     Diags.Report(ExistingModule->getValue()->DefinitionLoc,
431                  diag::note_mmap_prev_definition);
432 
433     // Skip the module definition.
434     skipUntil(MMToken::RBrace);
435     if (Tok.is(MMToken::RBrace))
436       consumeToken();
437 
438     HadError = true;
439     return;
440   }
441 
442   // Start defining this module.
443   ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework,
444                             Explicit);
445   ModuleSpace[ModuleName] = ActiveModule;
446 
447   bool Done = false;
448   do {
449     switch (Tok.Kind) {
450     case MMToken::EndOfFile:
451     case MMToken::RBrace:
452       Done = true;
453       break;
454 
455     case MMToken::ExplicitKeyword:
456     case MMToken::ModuleKeyword:
457       parseModuleDecl();
458       break;
459 
460     case MMToken::HeaderKeyword:
461       parseHeaderDecl();
462       break;
463 
464     case MMToken::UmbrellaKeyword:
465       parseUmbrellaDecl();
466       break;
467 
468     default:
469       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
470       consumeToken();
471       break;
472     }
473   } while (!Done);
474 
475   if (Tok.is(MMToken::RBrace))
476     consumeToken();
477   else {
478     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
479     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
480     HadError = true;
481   }
482 
483   // We're done parsing this module. Pop back to our parent scope.
484   ActiveModule = ActiveModule->Parent;
485 }
486 
487 /// \brief Parse an umbrella header declaration.
488 ///
489 ///   umbrella-declaration:
490 ///     'umbrella' string-literal
491 void ModuleMapParser::parseUmbrellaDecl() {
492   assert(Tok.is(MMToken::UmbrellaKeyword));
493   SourceLocation UmbrellaLoc = consumeToken();
494 
495   // Parse the header name.
496   if (!Tok.is(MMToken::StringLiteral)) {
497     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
498       << "umbrella";
499     HadError = true;
500     return;
501   }
502   StringRef FileName = Tok.getString();
503   SourceLocation FileNameLoc = consumeToken();
504 
505   // Check whether we already have an umbrella header.
506   if (ActiveModule->UmbrellaHeader) {
507     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict)
508       << ActiveModule->getFullModuleName()
509       << ActiveModule->UmbrellaHeader->getName();
510     HadError = true;
511     return;
512   }
513 
514   // Only top-level modules can have umbrella headers.
515   if (ActiveModule->Parent) {
516     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_header_submodule)
517       << ActiveModule->getFullModuleName();
518     HadError = true;
519     return;
520   }
521 
522   // Look for this file.
523   llvm::SmallString<128> PathName;
524   const FileEntry *File = 0;
525 
526   if (llvm::sys::path::is_absolute(FileName)) {
527     PathName = FileName;
528     File = SourceMgr.getFileManager().getFile(PathName);
529   } else {
530     // Search for the header file within the search directory.
531     PathName += Directory->getName();
532     unsigned PathLength = PathName.size();
533     if (ActiveModule->isPartOfFramework()) {
534       // Check whether this file is in the public headers.
535       llvm::sys::path::append(PathName, "Headers");
536       llvm::sys::path::append(PathName, FileName);
537       File = SourceMgr.getFileManager().getFile(PathName);
538 
539       if (!File) {
540         // Check whether this file is in the private headers.
541         PathName.resize(PathLength);
542         llvm::sys::path::append(PathName, "PrivateHeaders");
543         llvm::sys::path::append(PathName, FileName);
544         File = SourceMgr.getFileManager().getFile(PathName);
545       }
546 
547       // FIXME: Deal with subframeworks.
548     } else {
549       // Lookup for normal headers.
550       llvm::sys::path::append(PathName, FileName);
551       File = SourceMgr.getFileManager().getFile(PathName);
552     }
553   }
554 
555   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
556   // Come up with a lazy way to do this.
557   if (File) {
558     if (const Module *OwningModule = Map.Headers[File]) {
559       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
560         << FileName << OwningModule->getFullModuleName();
561       HadError = true;
562     } else if ((OwningModule = Map.UmbrellaDirs[Directory])) {
563       Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
564         << OwningModule->getFullModuleName();
565       HadError = true;
566     } else {
567       // Record this umbrella header.
568       ActiveModule->UmbrellaHeader = File;
569       Map.Headers[File] = ActiveModule;
570       Map.UmbrellaDirs[Directory] = ActiveModule;
571     }
572   } else {
573     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
574       << true << FileName;
575     HadError = true;
576   }
577 }
578 
579 /// \brief Parse a header declaration.
580 ///
581 ///   header-declaration:
582 ///     'header' string-literal
583 void ModuleMapParser::parseHeaderDecl() {
584   assert(Tok.is(MMToken::HeaderKeyword));
585   consumeToken();
586 
587   // Parse the header name.
588   if (!Tok.is(MMToken::StringLiteral)) {
589     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
590       << "header";
591     HadError = true;
592     return;
593   }
594   StringRef FileName = Tok.getString();
595   SourceLocation FileNameLoc = consumeToken();
596 
597   // Look for this file.
598   llvm::SmallString<128> PathName;
599   if (llvm::sys::path::is_relative(FileName)) {
600     // FIXME: Change this search to also look for private headers!
601     PathName += Directory->getName();
602 
603     if (ActiveModule->isPartOfFramework())
604       llvm::sys::path::append(PathName, "Headers");
605   }
606 
607   llvm::sys::path::append(PathName, FileName);
608 
609   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
610   // Come up with a lazy way to do this.
611   if (const FileEntry *File = SourceMgr.getFileManager().getFile(PathName)) {
612     if (const Module *OwningModule = Map.Headers[File]) {
613       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
614         << FileName << OwningModule->getFullModuleName();
615       HadError = true;
616     } else {
617       // Record this file.
618       ActiveModule->Headers.push_back(File);
619       Map.Headers[File] = ActiveModule;
620     }
621   } else {
622     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
623       << false << FileName;
624     HadError = true;
625   }
626 }
627 
628 /// \brief Parse a module map file.
629 ///
630 ///   module-map-file:
631 ///     module-declaration*
632 bool ModuleMapParser::parseModuleMapFile() {
633   do {
634     switch (Tok.Kind) {
635     case MMToken::EndOfFile:
636       return HadError;
637 
638     case MMToken::ModuleKeyword:
639     case MMToken::FrameworkKeyword:
640       parseModuleDecl();
641       break;
642 
643     case MMToken::ExplicitKeyword:
644     case MMToken::HeaderKeyword:
645     case MMToken::Identifier:
646     case MMToken::LBrace:
647     case MMToken::RBrace:
648     case MMToken::StringLiteral:
649     case MMToken::UmbrellaKeyword:
650       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
651       HadError = true;
652       consumeToken();
653       break;
654     }
655   } while (true);
656 
657   return HadError;
658 }
659 
660 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
661   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
662   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
663   if (!Buffer)
664     return true;
665 
666   // Parse this module map file.
667   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts);
668   Diags->getClient()->BeginSourceFile(LangOpts);
669   ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir());
670   bool Result = Parser.parseModuleMapFile();
671   Diags->getClient()->EndSourceFile();
672 
673   return Result;
674 }
675