blob: a0caf03e7769ca7b1e1e236583b6f24ef79c996c [file] [log] [blame]
Douglas Gregora30cfe52011-11-11 19:10:28 +00001//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ModuleMap implementation, which describes the layout
11// of a module as it relates to headers.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/Lex/ModuleMap.h"
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"
Douglas Gregorac252a32011-12-06 19:39:29 +000023#include "llvm/Support/FileSystem.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000024#include "llvm/Support/Host.h"
Douglas Gregor8b6d3de2011-11-11 21:55:48 +000025#include "llvm/Support/PathV2.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000026#include "llvm/Support/raw_ostream.h"
27#include "llvm/ADT/StringRef.h"
28#include "llvm/ADT/StringSwitch.h"
Douglas Gregor98cfcbf2012-09-27 14:50:15 +000029#include <stdlib.h>
Douglas Gregora30cfe52011-11-11 19:10:28 +000030using namespace clang;
31
Douglas Gregor90db2602011-12-02 01:47:07 +000032Module::ExportDecl
33ModuleMap::resolveExport(Module *Mod,
34 const Module::UnresolvedExportDecl &Unresolved,
35 bool Complain) {
Douglas Gregor0adaa882011-12-05 17:28:06 +000036 // We may have just a wildcard.
37 if (Unresolved.Id.empty()) {
38 assert(Unresolved.Wildcard && "Invalid unresolved export");
39 return Module::ExportDecl(0, true);
40 }
41
Douglas Gregor90db2602011-12-02 01:47:07 +000042 // Find the starting module.
43 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
44 if (!Context) {
45 if (Complain)
46 Diags->Report(Unresolved.Id[0].second,
47 diag::err_mmap_missing_module_unqualified)
48 << Unresolved.Id[0].first << Mod->getFullModuleName();
49
50 return Module::ExportDecl();
51 }
52
53 // Dig into the module path.
54 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
55 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
56 Context);
57 if (!Sub) {
58 if (Complain)
59 Diags->Report(Unresolved.Id[I].second,
60 diag::err_mmap_missing_module_qualified)
61 << Unresolved.Id[I].first << Context->getFullModuleName()
62 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
63
64 return Module::ExportDecl();
65 }
66
67 Context = Sub;
68 }
69
70 return Module::ExportDecl(Context, Unresolved.Wildcard);
71}
72
Douglas Gregor51f564f2011-12-31 04:05:44 +000073ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
Douglas Gregordc58aa72012-01-30 06:01:29 +000074 const LangOptions &LangOpts, const TargetInfo *Target)
Douglas Gregor2f04f182012-02-02 18:42:48 +000075 : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000076{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000077 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
78 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregora30cfe52011-11-11 19:10:28 +000079 new DiagnosticsEngine(DiagIDs));
80 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
81 SourceMgr = new SourceManager(*Diags, FileMgr);
82}
83
84ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +000085 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
86 IEnd = Modules.end();
87 I != IEnd; ++I) {
88 delete I->getValue();
89 }
90
Douglas Gregora30cfe52011-11-11 19:10:28 +000091 delete SourceMgr;
92}
93
Douglas Gregordc58aa72012-01-30 06:01:29 +000094void ModuleMap::setTarget(const TargetInfo &Target) {
95 assert((!this->Target || this->Target == &Target) &&
96 "Improper target override");
97 this->Target = &Target;
98}
99
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000100Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000101 llvm::DenseMap<const FileEntry *, Module *>::iterator Known
102 = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000103 if (Known != Headers.end()) {
104 // If a header corresponds to an unavailable module, don't report
105 // that it maps to anything.
106 if (!Known->second->isAvailable())
107 return 0;
108
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000109 return Known->second;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000110 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000111
Douglas Gregoradb97992011-11-16 23:02:25 +0000112 const DirectoryEntry *Dir = File->getDir();
Douglas Gregoradb97992011-11-16 23:02:25 +0000113 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
114 StringRef DirName = Dir->getName();
Douglas Gregore209e502011-12-06 01:10:29 +0000115
116 // Keep walking up the directory hierarchy, looking for a directory with
117 // an umbrella header.
118 do {
119 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
120 = UmbrellaDirs.find(Dir);
121 if (KnownDir != UmbrellaDirs.end()) {
122 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000123
124 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000125 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000126 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000127 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000128 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000129
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000130 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000131 // Infer submodules for each of the directories we found between
132 // the directory of the umbrella header and the directory where
133 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000134 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000135
Douglas Gregor6a1db482011-12-09 02:04:43 +0000136 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000137 // Find or create the module that corresponds to this directory name.
138 StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
139 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000140 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000141
142 // Associate the module and the directory.
143 UmbrellaDirs[SkippedDirs[I-1]] = Result;
144
145 // If inferred submodules export everything they import, add a
146 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000147 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000148 Result->Exports.push_back(Module::ExportDecl(0, true));
149 }
150
151 // Infer a submodule with the same name as this header file.
152 StringRef Name = llvm::sys::path::stem(File->getName());
153 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000154 Explicit).first;
Argyrios Kyrtzidisc7782d92012-10-05 00:22:33 +0000155 Result->TopHeaders.insert(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000156
157 // If inferred submodules export everything they import, add a
158 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000159 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000160 Result->Exports.push_back(Module::ExportDecl(0, true));
161 } else {
162 // Record each of the directories we stepped through as being part of
163 // the module we found, since the umbrella header covers them all.
164 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
165 UmbrellaDirs[SkippedDirs[I]] = Result;
166 }
167
168 Headers[File] = Result;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000169
170 // If a header corresponds to an unavailable module, don't report
171 // that it maps to anything.
172 if (!Result->isAvailable())
173 return 0;
174
Douglas Gregore209e502011-12-06 01:10:29 +0000175 return Result;
176 }
177
178 SkippedDirs.push_back(Dir);
179
Douglas Gregoradb97992011-11-16 23:02:25 +0000180 // Retrieve our parent path.
181 DirName = llvm::sys::path::parent_path(DirName);
182 if (DirName.empty())
183 break;
184
185 // Resolve the parent path to a directory entry.
186 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000187 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000188
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000189 return 0;
190}
191
Douglas Gregor51f564f2011-12-31 04:05:44 +0000192bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
193 llvm::DenseMap<const FileEntry *, Module *>::iterator Known
194 = Headers.find(Header);
195 if (Known != Headers.end())
196 return !Known->second->isAvailable();
197
198 const DirectoryEntry *Dir = Header->getDir();
199 llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
200 StringRef DirName = Dir->getName();
201
202 // Keep walking up the directory hierarchy, looking for a directory with
203 // an umbrella header.
204 do {
205 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
206 = UmbrellaDirs.find(Dir);
207 if (KnownDir != UmbrellaDirs.end()) {
208 Module *Found = KnownDir->second;
209 if (!Found->isAvailable())
210 return true;
211
212 // Search up the module stack until we find a module with an umbrella
213 // directory.
214 Module *UmbrellaModule = Found;
215 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
216 UmbrellaModule = UmbrellaModule->Parent;
217
218 if (UmbrellaModule->InferSubmodules) {
219 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
220 // Find or create the module that corresponds to this directory name.
221 StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
222 Found = lookupModuleQualified(Name, Found);
223 if (!Found)
224 return false;
225 if (!Found->isAvailable())
226 return true;
227 }
228
229 // Infer a submodule with the same name as this header file.
230 StringRef Name = llvm::sys::path::stem(Header->getName());
231 Found = lookupModuleQualified(Name, Found);
232 if (!Found)
233 return false;
234 }
235
236 return !Found->isAvailable();
237 }
238
239 SkippedDirs.push_back(Dir);
240
241 // Retrieve our parent path.
242 DirName = llvm::sys::path::parent_path(DirName);
243 if (DirName.empty())
244 break;
245
246 // Resolve the parent path to a directory entry.
247 Dir = SourceMgr->getFileManager().getDirectory(DirName);
248 } while (Dir);
249
250 return false;
251}
252
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000253Module *ModuleMap::findModule(StringRef Name) {
Douglas Gregor484535e2011-11-11 23:20:24 +0000254 llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
255 if (Known != Modules.end())
256 return Known->getValue();
257
258 return 0;
259}
260
Douglas Gregor90db2602011-12-02 01:47:07 +0000261Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
262 for(; Context; Context = Context->Parent) {
263 if (Module *Sub = lookupModuleQualified(Name, Context))
264 return Sub;
265 }
266
267 return findModule(Name);
268}
269
270Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
271 if (!Context)
272 return findModule(Name);
273
Douglas Gregorb7a78192012-01-04 23:32:19 +0000274 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000275}
276
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000277std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000278ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
279 bool IsExplicit) {
280 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000281 if (Module *Sub = lookupModuleQualified(Name, Parent))
282 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000283
284 // Create a new module with this name.
285 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
286 IsExplicit);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000287 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000288 Modules[Name] = Result;
289 return std::make_pair(Result, true);
290}
291
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000292Module *
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000293ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000294 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000295 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000296 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000297 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000298 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
299 return Mod;
300
301 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000302
303 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000304 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000305 llvm::sys::path::append(UmbrellaName, "Headers");
306 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000307 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000308
309 // FIXME: If there's no umbrella header, we could probably scan the
310 // framework to load *everything*. But, it's not clear that this is a good
311 // idea.
312 if (!UmbrellaHeader)
313 return 0;
314
Douglas Gregorac252a32011-12-06 19:39:29 +0000315 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
316 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000317 if (IsSystem)
318 Result->IsSystem = IsSystem;
319
Douglas Gregorb7a78192012-01-04 23:32:19 +0000320 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000321 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000322
Douglas Gregor489ad432011-12-08 18:00:48 +0000323 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000324 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000325 Headers[UmbrellaHeader] = Result;
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000326 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000327
328 // export *
329 Result->Exports.push_back(Module::ExportDecl(0, true));
330
Douglas Gregore209e502011-12-06 01:10:29 +0000331 // module * { export * }
332 Result->InferSubmodules = true;
333 Result->InferExportWildcard = true;
334
Douglas Gregorac252a32011-12-06 19:39:29 +0000335 // Look for subframeworks.
336 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000337 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000338 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000339 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000340 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000341 llvm::sys::path::native(SubframeworksDirName.str(),
342 SubframeworksDirNameNative);
343 for (llvm::sys::fs::directory_iterator
344 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000345 Dir != DirEnd && !EC; Dir.increment(EC)) {
346 if (!StringRef(Dir->path()).endswith(".framework"))
347 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000348
Douglas Gregorac252a32011-12-06 19:39:29 +0000349 if (const DirectoryEntry *SubframeworkDir
350 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000351 // Note: as an egregious but useful hack, we use the real path here and
352 // check whether it is actually a subdirectory of the parent directory.
353 // This will not be the case if the 'subframework' is actually a symlink
354 // out to a top-level framework.
355#ifdef LLVM_ON_UNIX
356 char RealSubframeworkDirName[PATH_MAX];
357 if (realpath(Dir->path().c_str(), RealSubframeworkDirName)) {
358 StringRef SubframeworkDirName = RealSubframeworkDirName;
359
360 bool FoundParent = false;
361 do {
362 // Get the parent directory name.
363 SubframeworkDirName
364 = llvm::sys::path::parent_path(SubframeworkDirName);
365 if (SubframeworkDirName.empty())
366 break;
367
368 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
369 FoundParent = true;
370 break;
371 }
372 } while (true);
373
374 if (!FoundParent)
375 continue;
376 }
377#endif
378
Douglas Gregorac252a32011-12-06 19:39:29 +0000379 // FIXME: Do we want to warn about subframeworks without umbrella headers?
380 inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000381 IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000382 }
383 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000384
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000385 return Result;
386}
387
Douglas Gregore209e502011-12-06 01:10:29 +0000388void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
389 Headers[UmbrellaHeader] = Mod;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000390 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000391 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000392}
393
Douglas Gregor77d029f2011-12-08 19:11:24 +0000394void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
395 Mod->Umbrella = UmbrellaDir;
396 UmbrellaDirs[UmbrellaDir] = Mod;
397}
398
Douglas Gregore209e502011-12-06 01:10:29 +0000399void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) {
400 Mod->Headers.push_back(Header);
401 Headers[Header] = Mod;
402}
403
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000404const FileEntry *
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000405ModuleMap::getContainingModuleMapFile(Module *Module) {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000406 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
407 return 0;
408
409 return SourceMgr->getFileEntryForID(
410 SourceMgr->getFileID(Module->DefinitionLoc));
411}
412
Douglas Gregora30cfe52011-11-11 19:10:28 +0000413void ModuleMap::dump() {
414 llvm::errs() << "Modules:";
415 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
416 MEnd = Modules.end();
417 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000418 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000419
420 llvm::errs() << "Headers:";
421 for (llvm::DenseMap<const FileEntry *, Module *>::iterator
422 H = Headers.begin(),
423 HEnd = Headers.end();
424 H != HEnd; ++H) {
425 llvm::errs() << " \"" << H->first->getName() << "\" -> "
426 << H->second->getFullModuleName() << "\n";
427 }
428}
429
Douglas Gregor90db2602011-12-02 01:47:07 +0000430bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
431 bool HadError = false;
432 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
433 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
434 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000435 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000436 Mod->Exports.push_back(Export);
437 else
438 HadError = true;
439 }
440 Mod->UnresolvedExports.clear();
441 return HadError;
442}
443
Douglas Gregor55988682011-12-05 16:33:54 +0000444Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
445 if (Loc.isInvalid())
446 return 0;
447
448 // Use the expansion location to determine which module we're in.
449 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
450 if (!ExpansionLoc.isFileID())
451 return 0;
452
453
454 const SourceManager &SrcMgr = Loc.getManager();
455 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000456
Douglas Gregor303aae92012-01-06 17:19:32 +0000457 while (const FileEntry *ExpansionFile
458 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
459 // Find the module that owns this header (if any).
460 if (Module *Mod = findModuleForHeader(ExpansionFile))
461 return Mod;
462
463 // No module owns this header, so look up the inclusion chain to see if
464 // any included header has an associated module.
465 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
466 if (IncludeLoc.isInvalid())
467 return 0;
468
469 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
470 }
471
472 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000473}
474
Douglas Gregora30cfe52011-11-11 19:10:28 +0000475//----------------------------------------------------------------------------//
476// Module map file parser
477//----------------------------------------------------------------------------//
478
479namespace clang {
480 /// \brief A token in a module map file.
481 struct MMToken {
482 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000483 Comma,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000484 EndOfFile,
485 HeaderKeyword,
486 Identifier,
487 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000488 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000489 FrameworkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000490 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000491 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000492 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000493 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000494 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000495 StringLiteral,
496 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000497 RBrace,
498 LSquare,
499 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000500 } Kind;
501
502 unsigned Location;
503 unsigned StringLength;
504 const char *StringData;
505
506 void clear() {
507 Kind = EndOfFile;
508 Location = 0;
509 StringLength = 0;
510 StringData = 0;
511 }
512
513 bool is(TokenKind K) const { return Kind == K; }
514
515 SourceLocation getLocation() const {
516 return SourceLocation::getFromRawEncoding(Location);
517 }
518
519 StringRef getString() const {
520 return StringRef(StringData, StringLength);
521 }
522 };
523
524 class ModuleMapParser {
525 Lexer &L;
526 SourceManager &SourceMgr;
527 DiagnosticsEngine &Diags;
528 ModuleMap &Map;
529
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000530 /// \brief The directory that this module map resides in.
531 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000532
533 /// \brief The directory containing Clang-supplied headers.
534 const DirectoryEntry *BuiltinIncludeDir;
535
Douglas Gregora30cfe52011-11-11 19:10:28 +0000536 /// \brief Whether an error occurred.
537 bool HadError;
538
539 /// \brief Default target information, used only for string literal
540 /// parsing.
Benjamin Kramerc0b6dbe2012-03-29 14:07:03 +0000541 OwningPtr<TargetInfo> Target;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000542
543 /// \brief Stores string data for the various string literals referenced
544 /// during parsing.
545 llvm::BumpPtrAllocator StringData;
546
547 /// \brief The current token.
548 MMToken Tok;
549
550 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000551 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000552
553 /// \brief Consume the current token and return its location.
554 SourceLocation consumeToken();
555
556 /// \brief Skip tokens until we reach the a token with the given kind
557 /// (or the end of the file).
558 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000559
560 typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
561 ModuleId;
562 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000563 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000564 void parseRequiresDecl();
Douglas Gregor489ad432011-12-08 18:00:48 +0000565 void parseHeaderDecl(SourceLocation UmbrellaLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000566 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000567 void parseExportDecl();
Douglas Gregor1e123682011-12-05 22:27:44 +0000568 void parseInferredSubmoduleDecl(bool Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000569
Douglas Gregor6a1db482011-12-09 02:04:43 +0000570 const DirectoryEntry *getOverriddenHeaderSearchDir();
571
Douglas Gregora30cfe52011-11-11 19:10:28 +0000572 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000573 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
574 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000575 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000576 const DirectoryEntry *Directory,
577 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000578 : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000579 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
580 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000581 {
582 TargetOptions TargetOpts;
583 TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
Benjamin Kramerc0b6dbe2012-03-29 14:07:03 +0000584 Target.reset(TargetInfo::CreateTargetInfo(Diags, TargetOpts));
Douglas Gregora30cfe52011-11-11 19:10:28 +0000585
586 Tok.clear();
587 consumeToken();
588 }
589
590 bool parseModuleMapFile();
591 };
592}
593
594SourceLocation ModuleMapParser::consumeToken() {
595retry:
596 SourceLocation Result = Tok.getLocation();
597 Tok.clear();
598
599 Token LToken;
600 L.LexFromRawLexer(LToken);
601 Tok.Location = LToken.getLocation().getRawEncoding();
602 switch (LToken.getKind()) {
603 case tok::raw_identifier:
604 Tok.StringData = LToken.getRawIdentifierData();
605 Tok.StringLength = LToken.getLength();
606 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
607 .Case("header", MMToken::HeaderKeyword)
608 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000609 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000610 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000611 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000612 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000613 .Case("umbrella", MMToken::UmbrellaKeyword)
614 .Default(MMToken::Identifier);
615 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000616
617 case tok::comma:
618 Tok.Kind = MMToken::Comma;
619 break;
620
Douglas Gregora30cfe52011-11-11 19:10:28 +0000621 case tok::eof:
622 Tok.Kind = MMToken::EndOfFile;
623 break;
624
625 case tok::l_brace:
626 Tok.Kind = MMToken::LBrace;
627 break;
628
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000629 case tok::l_square:
630 Tok.Kind = MMToken::LSquare;
631 break;
632
Douglas Gregor90db2602011-12-02 01:47:07 +0000633 case tok::period:
634 Tok.Kind = MMToken::Period;
635 break;
636
Douglas Gregora30cfe52011-11-11 19:10:28 +0000637 case tok::r_brace:
638 Tok.Kind = MMToken::RBrace;
639 break;
640
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000641 case tok::r_square:
642 Tok.Kind = MMToken::RSquare;
643 break;
644
Douglas Gregor90db2602011-12-02 01:47:07 +0000645 case tok::star:
646 Tok.Kind = MMToken::Star;
647 break;
648
Douglas Gregora30cfe52011-11-11 19:10:28 +0000649 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000650 if (LToken.hasUDSuffix()) {
651 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
652 HadError = true;
653 goto retry;
654 }
655
Douglas Gregora30cfe52011-11-11 19:10:28 +0000656 // Parse the string literal.
657 LangOptions LangOpts;
658 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
659 if (StringLiteral.hadError)
660 goto retry;
661
662 // Copy the string literal into our string data allocator.
663 unsigned Length = StringLiteral.GetStringLength();
664 char *Saved = StringData.Allocate<char>(Length + 1);
665 memcpy(Saved, StringLiteral.GetString().data(), Length);
666 Saved[Length] = 0;
667
668 // Form the token.
669 Tok.Kind = MMToken::StringLiteral;
670 Tok.StringData = Saved;
671 Tok.StringLength = Length;
672 break;
673 }
674
675 case tok::comment:
676 goto retry;
677
678 default:
679 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
680 HadError = true;
681 goto retry;
682 }
683
684 return Result;
685}
686
687void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
688 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000689 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000690 do {
691 switch (Tok.Kind) {
692 case MMToken::EndOfFile:
693 return;
694
695 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000696 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000697 return;
698
699 ++braceDepth;
700 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000701
702 case MMToken::LSquare:
703 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
704 return;
705
706 ++squareDepth;
707 break;
708
Douglas Gregora30cfe52011-11-11 19:10:28 +0000709 case MMToken::RBrace:
710 if (braceDepth > 0)
711 --braceDepth;
712 else if (Tok.is(K))
713 return;
714 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000715
716 case MMToken::RSquare:
717 if (squareDepth > 0)
718 --squareDepth;
719 else if (Tok.is(K))
720 return;
721 break;
722
Douglas Gregora30cfe52011-11-11 19:10:28 +0000723 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000724 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000725 return;
726 break;
727 }
728
729 consumeToken();
730 } while (true);
731}
732
Douglas Gregor587986e2011-12-07 02:23:45 +0000733/// \brief Parse a module-id.
734///
735/// module-id:
736/// identifier
737/// identifier '.' module-id
738///
739/// \returns true if an error occurred, false otherwise.
740bool ModuleMapParser::parseModuleId(ModuleId &Id) {
741 Id.clear();
742 do {
743 if (Tok.is(MMToken::Identifier)) {
744 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
745 consumeToken();
746 } else {
747 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
748 return true;
749 }
750
751 if (!Tok.is(MMToken::Period))
752 break;
753
754 consumeToken();
755 } while (true);
756
757 return false;
758}
759
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000760namespace {
761 /// \brief Enumerates the known attributes.
762 enum AttributeKind {
763 /// \brief An unknown attribute.
764 AT_unknown,
765 /// \brief The 'system' attribute.
766 AT_system
767 };
768}
769
Douglas Gregora30cfe52011-11-11 19:10:28 +0000770/// \brief Parse a module declaration.
771///
772/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000773/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
774/// { module-member* }
775///
776/// attributes:
777/// attribute attributes
778/// attribute
779///
780/// attribute:
781/// [ identifier ]
Douglas Gregora30cfe52011-11-11 19:10:28 +0000782///
783/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +0000784/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000785/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +0000786/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +0000787/// export-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +0000788///
789/// submodule-declaration:
790/// module-declaration
791/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000792void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +0000793 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
794 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +0000795 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +0000796 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000797 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +0000798 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +0000799
Douglas Gregord620a842011-12-06 17:16:41 +0000800 // Parse 'explicit' keyword, if present.
801 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +0000802 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +0000803 Explicit = true;
804 }
805
806 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +0000807 if (Tok.is(MMToken::FrameworkKeyword)) {
808 consumeToken();
809 Framework = true;
810 }
Douglas Gregora30cfe52011-11-11 19:10:28 +0000811
812 // Parse 'module' keyword.
813 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +0000814 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000815 consumeToken();
816 HadError = true;
817 return;
818 }
819 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +0000820
821 // If we have a wildcard for the module name, this is an inferred submodule.
822 // Parse it.
823 if (Tok.is(MMToken::Star))
824 return parseInferredSubmoduleDecl(Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000825
826 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +0000827 ModuleId Id;
828 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000829 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +0000830 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000831 }
Douglas Gregor587986e2011-12-07 02:23:45 +0000832
833 if (ActiveModule) {
834 if (Id.size() > 1) {
835 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
836 << SourceRange(Id.front().second, Id.back().second);
837
838 HadError = true;
839 return;
840 }
841 } else if (Id.size() == 1 && Explicit) {
842 // Top-level modules can't be explicit.
843 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
844 Explicit = false;
845 ExplicitLoc = SourceLocation();
846 HadError = true;
847 }
848
849 Module *PreviousActiveModule = ActiveModule;
850 if (Id.size() > 1) {
851 // This module map defines a submodule. Go find the module of which it
852 // is a submodule.
853 ActiveModule = 0;
854 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
855 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
856 ActiveModule = Next;
857 continue;
858 }
859
860 if (ActiveModule) {
861 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
862 << Id[I].first << ActiveModule->getTopLevelModule();
863 } else {
864 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
865 }
866 HadError = true;
867 return;
868 }
869 }
870
871 StringRef ModuleName = Id.back().first;
872 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000873
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000874 // Parse the optional attribute list.
875 bool IsSystem = false;
876 while (Tok.is(MMToken::LSquare)) {
877 // Consume the '['.
878 SourceLocation LSquareLoc = consumeToken();
879
880 // Check whether we have an attribute name here.
881 if (!Tok.is(MMToken::Identifier)) {
882 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
883 skipUntil(MMToken::RSquare);
884 if (Tok.is(MMToken::RSquare))
885 consumeToken();
886 continue;
887 }
888
889 // Decode the attribute name.
890 AttributeKind Attribute
891 = llvm::StringSwitch<AttributeKind>(Tok.getString())
892 .Case("system", AT_system)
893 .Default(AT_unknown);
894 switch (Attribute) {
895 case AT_unknown:
896 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
897 << Tok.getString();
898 break;
899
900 case AT_system:
901 IsSystem = true;
902 break;
903 }
904 consumeToken();
905
906 // Consume the ']'.
907 if (!Tok.is(MMToken::RSquare)) {
908 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
909 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
910 skipUntil(MMToken::RSquare);
911 }
912
913 if (Tok.is(MMToken::RSquare))
914 consumeToken();
915 }
916
Douglas Gregora30cfe52011-11-11 19:10:28 +0000917 // Parse the opening brace.
918 if (!Tok.is(MMToken::LBrace)) {
919 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
920 << ModuleName;
921 HadError = true;
922 return;
923 }
924 SourceLocation LBraceLoc = consumeToken();
925
926 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000927 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +0000928 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
929 // Skip the module definition.
930 skipUntil(MMToken::RBrace);
931 if (Tok.is(MMToken::RBrace))
932 consumeToken();
933 else {
934 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
935 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
936 HadError = true;
937 }
938 return;
939 }
940
Douglas Gregora30cfe52011-11-11 19:10:28 +0000941 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
942 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000943 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000944
945 // Skip the module definition.
946 skipUntil(MMToken::RBrace);
947 if (Tok.is(MMToken::RBrace))
948 consumeToken();
949
950 HadError = true;
951 return;
952 }
953
954 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000955 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
956 Explicit).first;
957 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000958 if (IsSystem)
959 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000960
961 bool Done = false;
962 do {
963 switch (Tok.Kind) {
964 case MMToken::EndOfFile:
965 case MMToken::RBrace:
966 Done = true;
967 break;
968
969 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +0000970 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000971 case MMToken::ModuleKeyword:
972 parseModuleDecl();
973 break;
974
Douglas Gregor90db2602011-12-02 01:47:07 +0000975 case MMToken::ExportKeyword:
976 parseExportDecl();
977 break;
978
Douglas Gregor51f564f2011-12-31 04:05:44 +0000979 case MMToken::RequiresKeyword:
980 parseRequiresDecl();
981 break;
982
Douglas Gregor77d029f2011-12-08 19:11:24 +0000983 case MMToken::UmbrellaKeyword: {
984 SourceLocation UmbrellaLoc = consumeToken();
985 if (Tok.is(MMToken::HeaderKeyword))
986 parseHeaderDecl(UmbrellaLoc);
987 else
988 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000989 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +0000990 }
Douglas Gregora30cfe52011-11-11 19:10:28 +0000991
Douglas Gregor489ad432011-12-08 18:00:48 +0000992 case MMToken::HeaderKeyword:
993 parseHeaderDecl(SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +0000994 break;
Douglas Gregor489ad432011-12-08 18:00:48 +0000995
Douglas Gregora30cfe52011-11-11 19:10:28 +0000996 default:
997 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
998 consumeToken();
999 break;
1000 }
1001 } while (!Done);
1002
1003 if (Tok.is(MMToken::RBrace))
1004 consumeToken();
1005 else {
1006 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1007 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1008 HadError = true;
1009 }
1010
Douglas Gregor587986e2011-12-07 02:23:45 +00001011 // We're done parsing this module. Pop back to the previous module.
1012 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001013}
Douglas Gregord620a842011-12-06 17:16:41 +00001014
Douglas Gregor51f564f2011-12-31 04:05:44 +00001015/// \brief Parse a requires declaration.
1016///
1017/// requires-declaration:
1018/// 'requires' feature-list
1019///
1020/// feature-list:
1021/// identifier ',' feature-list
1022/// identifier
1023void ModuleMapParser::parseRequiresDecl() {
1024 assert(Tok.is(MMToken::RequiresKeyword));
1025
1026 // Parse 'requires' keyword.
1027 consumeToken();
1028
1029 // Parse the feature-list.
1030 do {
1031 if (!Tok.is(MMToken::Identifier)) {
1032 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1033 HadError = true;
1034 return;
1035 }
1036
1037 // Consume the feature name.
1038 std::string Feature = Tok.getString();
1039 consumeToken();
1040
1041 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001042 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001043
1044 if (!Tok.is(MMToken::Comma))
1045 break;
1046
1047 // Consume the comma.
1048 consumeToken();
1049 } while (true);
1050}
1051
Douglas Gregord620a842011-12-06 17:16:41 +00001052/// \brief Append to \p Paths the set of paths needed to get to the
1053/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001054static void appendSubframeworkPaths(Module *Mod,
1055 llvm::SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001056 // Collect the framework names from the given module to the top-level module.
1057 llvm::SmallVector<StringRef, 2> Paths;
1058 for (; Mod; Mod = Mod->Parent) {
1059 if (Mod->IsFramework)
1060 Paths.push_back(Mod->Name);
1061 }
1062
1063 if (Paths.empty())
1064 return;
1065
1066 // Add Frameworks/Name.framework for each subframework.
1067 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1068 llvm::sys::path::append(Path, "Frameworks");
1069 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1070 }
1071}
1072
Douglas Gregor2f04f182012-02-02 18:42:48 +00001073/// \brief Determine whether the given file name is the name of a builtin
1074/// header, supplied by Clang to replace, override, or augment existing system
1075/// headers.
1076static bool isBuiltinHeader(StringRef FileName) {
1077 return llvm::StringSwitch<bool>(FileName)
1078 .Case("float.h", true)
1079 .Case("iso646.h", true)
1080 .Case("limits.h", true)
1081 .Case("stdalign.h", true)
1082 .Case("stdarg.h", true)
1083 .Case("stdbool.h", true)
1084 .Case("stddef.h", true)
1085 .Case("stdint.h", true)
1086 .Case("tgmath.h", true)
1087 .Case("unwind.h", true)
1088 .Default(false);
1089}
1090
Douglas Gregora30cfe52011-11-11 19:10:28 +00001091/// \brief Parse a header declaration.
1092///
1093/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001094/// 'umbrella'[opt] 'header' string-literal
1095void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001096 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001097 consumeToken();
1098
Douglas Gregor489ad432011-12-08 18:00:48 +00001099 bool Umbrella = UmbrellaLoc.isValid();
1100
Douglas Gregora30cfe52011-11-11 19:10:28 +00001101 // Parse the header name.
1102 if (!Tok.is(MMToken::StringLiteral)) {
1103 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1104 << "header";
1105 HadError = true;
1106 return;
1107 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001108 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001109 SourceLocation FileNameLoc = consumeToken();
1110
Douglas Gregor77d029f2011-12-08 19:11:24 +00001111 // Check whether we already have an umbrella.
1112 if (Umbrella && ActiveModule->Umbrella) {
1113 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1114 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001115 HadError = true;
1116 return;
1117 }
1118
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001119 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001120 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001121 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001122 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001123 if (llvm::sys::path::is_absolute(FileName)) {
1124 PathName = FileName;
1125 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001126 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1127 PathName = Dir->getName();
1128 llvm::sys::path::append(PathName, FileName);
1129 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001130 } else {
1131 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001132 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001133 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001134
Douglas Gregord620a842011-12-06 17:16:41 +00001135 if (ActiveModule->isPartOfFramework()) {
1136 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001137
1138 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001139 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001140 llvm::sys::path::append(PathName, FileName);
1141 File = SourceMgr.getFileManager().getFile(PathName);
1142
1143 if (!File) {
1144 // Check whether this file is in the private headers.
1145 PathName.resize(PathLength);
1146 llvm::sys::path::append(PathName, "PrivateHeaders");
1147 llvm::sys::path::append(PathName, FileName);
1148 File = SourceMgr.getFileManager().getFile(PathName);
1149 }
1150 } else {
1151 // Lookup for normal headers.
1152 llvm::sys::path::append(PathName, FileName);
1153 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001154
1155 // If this is a system module with a top-level header, this header
1156 // may have a counterpart (or replacement) in the set of headers
1157 // supplied by Clang. Find that builtin header.
1158 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1159 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001160 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001161 llvm::sys::path::append(BuiltinPathName, FileName);
1162 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1163
1164 // If Clang supplies this header but the underlying system does not,
1165 // just silently swap in our builtin version. Otherwise, we'll end
1166 // up adding both (later).
1167 if (!File && BuiltinFile) {
1168 File = BuiltinFile;
1169 BuiltinFile = 0;
1170 }
1171 }
Douglas Gregord620a842011-12-06 17:16:41 +00001172 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001173 }
Douglas Gregora8654052011-11-17 22:09:43 +00001174
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001175 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1176 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001177 if (File) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001178 if (const Module *OwningModule = Map.Headers[File]) {
1179 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
1180 << FileName << OwningModule->getFullModuleName();
1181 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001182 } else if (Umbrella) {
1183 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor489ad432011-12-08 18:00:48 +00001184 if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) {
1185 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1186 << OwningModule->getFullModuleName();
1187 HadError = true;
1188 } else {
1189 // Record this umbrella header.
1190 Map.setUmbrellaHeader(ActiveModule, File);
1191 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001192 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001193 // Record this header.
Douglas Gregore209e502011-12-06 01:10:29 +00001194 Map.addHeader(ActiveModule, File);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001195
1196 // If there is a builtin counterpart to this file, add it now.
1197 if (BuiltinFile)
1198 Map.addHeader(ActiveModule, BuiltinFile);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001199 }
1200 } else {
1201 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001202 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001203 HadError = true;
1204 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001205}
1206
Douglas Gregor77d029f2011-12-08 19:11:24 +00001207/// \brief Parse an umbrella directory declaration.
1208///
1209/// umbrella-dir-declaration:
1210/// umbrella string-literal
1211void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1212 // Parse the directory name.
1213 if (!Tok.is(MMToken::StringLiteral)) {
1214 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1215 << "umbrella";
1216 HadError = true;
1217 return;
1218 }
1219
1220 std::string DirName = Tok.getString();
1221 SourceLocation DirNameLoc = consumeToken();
1222
1223 // Check whether we already have an umbrella.
1224 if (ActiveModule->Umbrella) {
1225 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1226 << ActiveModule->getFullModuleName();
1227 HadError = true;
1228 return;
1229 }
1230
1231 // Look for this file.
1232 const DirectoryEntry *Dir = 0;
1233 if (llvm::sys::path::is_absolute(DirName))
1234 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1235 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001236 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001237 PathName = Directory->getName();
1238 llvm::sys::path::append(PathName, DirName);
1239 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1240 }
1241
1242 if (!Dir) {
1243 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1244 << DirName;
1245 HadError = true;
1246 return;
1247 }
1248
1249 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1250 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1251 << OwningModule->getFullModuleName();
1252 HadError = true;
1253 return;
1254 }
1255
1256 // Record this umbrella directory.
1257 Map.setUmbrellaDir(ActiveModule, Dir);
1258}
1259
Douglas Gregor90db2602011-12-02 01:47:07 +00001260/// \brief Parse a module export declaration.
1261///
1262/// export-declaration:
1263/// 'export' wildcard-module-id
1264///
1265/// wildcard-module-id:
1266/// identifier
1267/// '*'
1268/// identifier '.' wildcard-module-id
1269void ModuleMapParser::parseExportDecl() {
1270 assert(Tok.is(MMToken::ExportKeyword));
1271 SourceLocation ExportLoc = consumeToken();
1272
1273 // Parse the module-id with an optional wildcard at the end.
1274 ModuleId ParsedModuleId;
1275 bool Wildcard = false;
1276 do {
1277 if (Tok.is(MMToken::Identifier)) {
1278 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1279 Tok.getLocation()));
1280 consumeToken();
1281
1282 if (Tok.is(MMToken::Period)) {
1283 consumeToken();
1284 continue;
1285 }
1286
1287 break;
1288 }
1289
1290 if(Tok.is(MMToken::Star)) {
1291 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001292 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001293 break;
1294 }
1295
1296 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1297 HadError = true;
1298 return;
1299 } while (true);
1300
1301 Module::UnresolvedExportDecl Unresolved = {
1302 ExportLoc, ParsedModuleId, Wildcard
1303 };
1304 ActiveModule->UnresolvedExports.push_back(Unresolved);
1305}
1306
Douglas Gregor1e123682011-12-05 22:27:44 +00001307void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) {
1308 assert(Tok.is(MMToken::Star));
1309 SourceLocation StarLoc = consumeToken();
1310 bool Failed = false;
1311
1312 // Inferred modules must be submodules.
1313 if (!ActiveModule) {
1314 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1315 Failed = true;
1316 }
1317
Douglas Gregor77d029f2011-12-08 19:11:24 +00001318 // Inferred modules must have umbrella directories.
1319 if (!Failed && !ActiveModule->getUmbrellaDir()) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001320 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1321 Failed = true;
1322 }
1323
1324 // Check for redefinition of an inferred module.
Douglas Gregoref85b562011-12-06 17:34:58 +00001325 if (!Failed && ActiveModule->InferSubmodules) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001326 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
Douglas Gregoref85b562011-12-06 17:34:58 +00001327 if (ActiveModule->InferredSubmoduleLoc.isValid())
1328 Diags.Report(ActiveModule->InferredSubmoduleLoc,
Douglas Gregor1e123682011-12-05 22:27:44 +00001329 diag::note_mmap_prev_definition);
1330 Failed = true;
1331 }
1332
1333 // If there were any problems with this inferred submodule, skip its body.
1334 if (Failed) {
1335 if (Tok.is(MMToken::LBrace)) {
1336 consumeToken();
1337 skipUntil(MMToken::RBrace);
1338 if (Tok.is(MMToken::RBrace))
1339 consumeToken();
1340 }
1341 HadError = true;
1342 return;
1343 }
1344
1345 // Note that we have an inferred submodule.
Douglas Gregoref85b562011-12-06 17:34:58 +00001346 ActiveModule->InferSubmodules = true;
1347 ActiveModule->InferredSubmoduleLoc = StarLoc;
1348 ActiveModule->InferExplicitSubmodules = Explicit;
Douglas Gregor1e123682011-12-05 22:27:44 +00001349
1350 // Parse the opening brace.
1351 if (!Tok.is(MMToken::LBrace)) {
1352 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1353 HadError = true;
1354 return;
1355 }
1356 SourceLocation LBraceLoc = consumeToken();
1357
1358 // Parse the body of the inferred submodule.
1359 bool Done = false;
1360 do {
1361 switch (Tok.Kind) {
1362 case MMToken::EndOfFile:
1363 case MMToken::RBrace:
1364 Done = true;
1365 break;
1366
1367 case MMToken::ExportKeyword: {
1368 consumeToken();
1369 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001370 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001371 else
1372 Diags.Report(Tok.getLocation(),
1373 diag::err_mmap_expected_export_wildcard);
1374 consumeToken();
1375 break;
1376 }
1377
1378 case MMToken::ExplicitKeyword:
1379 case MMToken::ModuleKeyword:
1380 case MMToken::HeaderKeyword:
1381 case MMToken::UmbrellaKeyword:
1382 default:
1383 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member);
1384 consumeToken();
1385 break;
1386 }
1387 } while (!Done);
1388
1389 if (Tok.is(MMToken::RBrace))
1390 consumeToken();
1391 else {
1392 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1393 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1394 HadError = true;
1395 }
1396}
1397
Douglas Gregor6a1db482011-12-09 02:04:43 +00001398/// \brief If there is a specific header search directory due the presence
1399/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1400const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1401 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1402 // If we have an umbrella directory, use that.
1403 if (Mod->hasUmbrellaDir())
1404 return Mod->getUmbrellaDir();
1405
1406 // If we have a framework directory, stop looking.
1407 if (Mod->IsFramework)
1408 return 0;
1409 }
1410
1411 return 0;
1412}
1413
Douglas Gregora30cfe52011-11-11 19:10:28 +00001414/// \brief Parse a module map file.
1415///
1416/// module-map-file:
1417/// module-declaration*
1418bool ModuleMapParser::parseModuleMapFile() {
1419 do {
1420 switch (Tok.Kind) {
1421 case MMToken::EndOfFile:
1422 return HadError;
1423
Douglas Gregor587986e2011-12-07 02:23:45 +00001424 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001425 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001426 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001427 parseModuleDecl();
1428 break;
1429
Douglas Gregor51f564f2011-12-31 04:05:44 +00001430 case MMToken::Comma:
Douglas Gregor90db2602011-12-02 01:47:07 +00001431 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001432 case MMToken::HeaderKeyword:
1433 case MMToken::Identifier:
1434 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001435 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001436 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001437 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001438 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001439 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001440 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001441 case MMToken::StringLiteral:
1442 case MMToken::UmbrellaKeyword:
1443 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1444 HadError = true;
1445 consumeToken();
1446 break;
1447 }
1448 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001449}
1450
1451bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregordc58aa72012-01-30 06:01:29 +00001452 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001453 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1454 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1455 if (!Buffer)
1456 return true;
1457
1458 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001459 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1460 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001461 ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir(),
1462 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001463 bool Result = Parser.parseModuleMapFile();
1464 Diags->getClient()->EndSourceFile();
1465
1466 return Result;
1467}