clang: lib/Lex/ModuleMap.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

28#include "llvm/ADT/DenseMap.h"

29#include "llvm/ADT/STLExtras.h"

30#include "llvm/ADT/SmallPtrSet.h"

31#include "llvm/ADT/SmallVector.h"

32#include "llvm/ADT/StringMap.h"

33#include "llvm/ADT/StringRef.h"

34#include "llvm/ADT/StringSwitch.h"

35#include "llvm/Support/Compiler.h"

36#include "llvm/Support/ErrorHandling.h"

37#include "llvm/Support/Path.h"

38#include "llvm/Support/VirtualFileSystem.h"

39#include "llvm/Support/raw_ostream.h"

40#include

41#include

42#include

43#include

44#include <system_error>

45#include

46

47using namespace clang;

48

49void ModuleMapCallbacks::anchor() {}

50

52 auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);

53 if (PendingLinkAs != PendingLinkAsModule.end()) {

54 for (auto &Name : PendingLinkAs->second) {

56 if (M)

57 M->UseExportAsModuleLinkName = true;

58 }

59 }

60}

61

68

70 switch ((int)Role) {

81 }

82 llvm_unreachable("unknown header role");

83}

84

87 switch ((int)Kind) {

98 }

99 llvm_unreachable("unknown header kind");

100}

101

105

107ModuleMap::resolveExport(Module *Mod,

109 bool Complain) const {

110

112 assert(Unresolved.Wildcard && "Invalid unresolved export");

114 }

115

116

117 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);

118 if (!Context)

119 return {};

120

122}

123

125 bool Complain) const {

126

128 if (!Context) {

129 if (Complain)

130 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)

132

133 return nullptr;

134 }

135

136

137 for (unsigned I = 1, N = Id.size(); I != N; ++I) {

139 if (!Sub) {

140 if (Complain)

141 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)

142 << Id[I].first << Context->getFullModuleName()

143 << SourceRange(Id[0].second, Id[I-1].second);

144

145 return nullptr;

146 }

147

148 Context = Sub;

149 }

150

151 return Context;

152}

153

154

155

158

160 for (; Mod; Mod = Mod->Parent) {

162 Paths.push_back(Mod->Name);

163 }

164

165 if (Paths.empty())

166 return;

167

168

169 for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))

170 llvm::sys::path::append(Path, "Frameworks", Framework + ".framework");

171}

172

176

178 SmallString<128> FullPathName(Directory->getName());

179

182 expectedToOptional(SourceMgr.getFileManager().getFileRef(Filename));

183 if (File || (Header.Size && File->getSize() != *Header.Size) ||

185 return std::nullopt;

186 return *File;

187 };

188

190 unsigned FullPathLength = FullPathName.size();

192 unsigned RelativePathLength = RelativePathName.size();

193

194

195 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);

196 llvm::sys::path::append(FullPathName, RelativePathName);

197 if (auto File = GetFile(FullPathName))

199

200

201

202

203

204

205

207 RelativePathName.clear();

208 else

209 RelativePathName.resize(RelativePathLength);

210 FullPathName.resize(FullPathLength);

211 llvm::sys::path::append(RelativePathName, "PrivateHeaders",

213 llvm::sys::path::append(FullPathName, RelativePathName);

214 return GetFile(FullPathName);

215 };

216

217 if (llvm::sys::path::is_absolute(Header.FileName)) {

218 RelativePathName.clear();

219 RelativePathName.append(Header.FileName.begin(), Header.FileName.end());

220 return GetFile(Header.FileName);

221 }

222

224 return GetFrameworkFile();

225

226

227 llvm::sys::path::append(RelativePathName, Header.FileName);

228 llvm::sys::path::append(FullPathName, RelativePathName);

229 auto NormalHdrFile = GetFile(FullPathName);

230

231 if (!NormalHdrFile && Directory->getName().ends_with(".framework")) {

232

233

234

235 FullPathName.assign(Directory->getName());

236 RelativePathName.clear();

237 if (GetFrameworkFile()) {

239 diag::warn_mmap_incomplete_framework_module_declaration)

241 NeedsFramework = true;

242 }

243 return std::nullopt;

244 }

245

246 return NormalHdrFile;

247}

248

249

250

251

253 return llvm::StringSwitch(FileName)

254 .Case("float.h", true)

255 .Case("iso646.h", true)

256 .Case("limits.h", true)

257 .Case("stdalign.h", true)

258 .Case("stdarg.h", true)

259 .Case("stdatomic.h", true)

260 .Case("stdbool.h", true)

261 .Case("stdckdint.h", true)

262 .Case("stdcountof.h", true)

263 .Case("stddef.h", true)

264 .Case("stdint.h", true)

265 .Case("tgmath.h", true)

266 .Case("unwind.h", true)

267 .Default(false);

268}

269

270

271

273 return llvm::StringSwitch(ModuleName)

274 .Case("_Builtin_float", true)

275 .Case("_Builtin_inttypes", true)

276 .Case("_Builtin_iso646", true)

277 .Case("_Builtin_limits", true)

278 .Case("_Builtin_stdalign", true)

279 .Case("_Builtin_stdarg", true)

280 .Case("_Builtin_stdatomic", true)

281 .Case("_Builtin_stdbool", true)

282 .Case("_Builtin_stddef", true)

283 .Case("_Builtin_stdint", true)

284 .Case("_Builtin_stdnoreturn", true)

285 .Case("_Builtin_tgmath", true)

286 .Case("_Builtin_unwind", true)

287 .Default(false);

288}

289

290void ModuleMap::resolveHeader(Module *Mod,

292 bool &NeedsFramework) {

293 SmallString<128> RelativePathName;

295 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {

297 const DirectoryEntry *UmbrellaDir = &File->getDir().getDirEntry();

298 if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])

299 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)

300 << UmbrellaMod->getFullModuleName();

301 else

302

304 RelativePathName.str());

305 } else {

306 Module::Header H = {Header.FileName, std::string(RelativePathName),

309 }

311

312

314

315 } else {

316

317

319

320

321

322

325 }

326}

327

328bool ModuleMap::resolveAsBuiltinHeader(

331 llvm::sys::path::is_absolute(Header.FileName) ||

333 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||

335 return false;

336

337

338

339

340 SmallString<128> Path;

341 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);

342 auto File = SourceMgr.getFileManager().getOptionalFileRef(Path);

344 return false;

345

349 return true;

350}

351

355 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),

356 HeaderInfo(HeaderInfo) {

357}

358

360

362 assert((!this->Target || this->Target == &Target) &&

363 "Improper target override");

364 this->Target = &Target;

365}

366

367

370 if (Name.empty())

371 return Name;

372

374

375

376 Buffer.clear();

378 Buffer.push_back('_');

379 Buffer.reserve(Buffer.size() + Name.size());

380 for (unsigned I = 0, N = Name.size(); I != N; ++I) {

382 Buffer.push_back(Name[I]);

383 else

384 Buffer.push_back('_');

385 }

386

387 Name = StringRef(Buffer.data(), Buffer.size());

388 }

389

390 while (llvm::StringSwitch(Name)

393#include "clang/Basic/TokenKinds.def"

395 if (Name.data() != Buffer.data())

396 Buffer.append(Name.begin(), Name.end());

397 Buffer.push_back('_');

398 Name = StringRef(Buffer.data(), Buffer.size());

399 }

400

401 return Name;

402}

403

405 return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&

407}

408

411 return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&

414}

415

416ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(FileEntryRef File) {

418 HeadersMap::iterator Known = Headers.find(File);

422 return Headers.find(File);

423 }

424 return Known;

425}

426

429 if (UmbrellaDirs.empty())

430 return {};

431

433

434

435

436

437

438 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(*Dir);

439

440

441

442 do {

443 auto KnownDir = UmbrellaDirs.find(*Dir);

444 if (KnownDir != UmbrellaDirs.end())

446

447 IntermediateDirs.push_back(*Dir);

448

449

450 DirName = llvm::sys::path::parent_path(DirName);

451 if (DirName.empty())

452 break;

453

454

455 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);

456 } while (Dir);

457 return {};

458}

459

463#ifndef NDEBUG

465

466

467

468 bool IsPrivate = false;

472 for (auto Hs : HeaderList)

473 IsPrivate |= llvm::any_of(

475 assert(IsPrivate && "inconsistent headers and roles");

476 }

477#endif

479}

480

484

486 bool RequestingModuleIsModuleInterface,

489

490

492 return;

493

494 if (RequestingModule) {

495 resolveUses(RequestingModule, false);

497 }

498

499 bool Excluded = false;

501 Module *NotUsed = nullptr;

502

503 HeadersMap::iterator Known = findKnownHeader(File);

504 if (Known != Headers.end()) {

505 for (const KnownHeader &Header : Known->second) {

506

508 Excluded = true;

509 continue;

510 }

511

512

515 continue;

516 }

517

518

519

520 if (RequestingModule && LangOpts.ModulesDeclUse &&

523 continue;

524 }

525

526

527 return;

528 }

529

530 Excluded = true;

531 }

532

533

535 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)

536 << Filename;

537 return;

538 }

539

540

541 if (NotUsed) {

542 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)

544 << NotUsed->Name;

545 return;

546 }

547

548 if (Excluded || isHeaderInUmbrellaDirs(File))

549 return;

550

551

552

553 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {

554 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)

556 } else if (RequestingModule && RequestingModuleIsModuleInterface &&

557 LangOpts.isCompilingModule()) {

558

560 diag::warn_non_modular_include_in_framework_module :

561 diag::warn_non_modular_include_in_module;

562 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()

563 << File.getName();

564 }

565}

566

569

570

571

572

574 return true;

575

576

580

581

585

586

590

591

592 return false;

593}

594

596 bool AllowTextual,

597 bool AllowExcluded) {

600 return {};

601 return R;

602 };

603

604 HeadersMap::iterator Known = findKnownHeader(File);

605 if (Known != Headers.end()) {

607

609

611 continue;

612

614 return MakeResult(H);

617 }

618 return MakeResult(Result);

619 }

620

621 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));

622}

623

625ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {

626 assert(!Headers.count(File) && "already have a module for this header");

627

629 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);

630 if (H) {

632

633

634

637 UmbrellaModule = UmbrellaModule->Parent;

638

641

642

643

644

646

647 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {

648

651 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);

655

656

657 UmbrellaDirs[SkippedDir] = Result;

658

659

660

663 }

664

665

668 llvm::sys::path::stem(File.getName()), NameBuf);

672 Result->addTopHeader(File);

673

674

675

678 } else {

679

680

681 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)

682 UmbrellaDirs[SkippedDirs[I]] = Result;

683 }

684

686 Headers[File].push_back(Header);

687 return Header;

688 }

689

690 return {};

691}

692

695 HeadersMap::iterator Known = findKnownHeader(File);

696 if (Known != Headers.end())

697 return Known->second;

698

699 if (findOrCreateModuleForHeaderInUmbrellaDir(File))

700 return Headers.find(File)->second;

701

702 return {};

703}

704

707

709 auto It = Headers.find(File);

710 if (It == Headers.end())

711 return {};

712 return It->second;

713}

714

718

722 HeadersMap::const_iterator Known = Headers.find(Header);

723 if (Known != Headers.end()) {

725 I = Known->second.begin(),

726 E = Known->second.end();

727 I != E; ++I) {

728

730 continue;

731

732 if (I->isAvailable() &&

733 (!RequestingModule ||

734 I->getModule()->isSubModuleOf(RequestingModule))) {

735

736

737

738

739

741 continue;

742 return false;

743 }

744 }

745 return true;

746 }

747

750 StringRef DirName = Dir->getName();

751

752 auto IsUnavailable = [&](const Module *M) {

753 return !M->isAvailable() && (!RequestingModule ||

755 };

756

757

758

759 do {

760 auto KnownDir = UmbrellaDirs.find(*Dir);

761 if (KnownDir != UmbrellaDirs.end()) {

763 if (IsUnavailable(Found))

764 return true;

765

766

767

770 UmbrellaModule->Parent)

771 UmbrellaModule = UmbrellaModule->Parent;

772

774 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {

775

778 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);

781 return false;

782 if (IsUnavailable(Found))

783 return true;

784 }

785

786

789 llvm::sys::path::stem(Header.getName()),

790 NameBuf);

793 return false;

794 }

795

796 return IsUnavailable(Found);

797 }

798

799 SkippedDirs.push_back(*Dir);

800

801

802 DirName = llvm::sys::path::parent_path(DirName);

803 if (DirName.empty())

804 break;

805

806

807 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);

808 } while (Dir);

809

810 return false;

811}

812

814 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);

815 if (Known != Modules.end())

816 return Known->getValue();

817

818 return nullptr;

819}

820

823 return SubM;

825 return nullptr;

826 Module *Result = new (ModulesAlloc.Allocate())

832 if (Result->InferExportWildcard)

835}

836

838 Module *Context) const {

839 for(; Context; Context = Context->Parent) {

841 return Sub;

842 }

843

845}

846

848 if (!Context)

850

851 return Context->findSubmodule(Name);

852}

853

856 bool IsFramework,

857 bool IsExplicit) {

858

860 return std::make_pair(Sub, false);

861

862

864 return std::make_pair(M, true);

865}

866

868 bool IsFramework, bool IsExplicit) {

870 "Creating duplicate submodule");

871

872 Module *Result = new (ModulesAlloc.Allocate())

874 IsFramework, IsExplicit, NumCreatedModules++);

875 if (!Parent) {

876 if (LangOpts.CurrentModule == Name)

877 SourceModule = Result;

878 Modules[Name] = Result;

879 ModuleScopeIDs[Result] = CurrentModuleScopeID;

880 }

882}

883

886 auto *Result = new (ModulesAlloc.Allocate()) Module(

888 true, NumCreatedModules++);

890

891

893 PendingSubmodules.emplace_back(Result);

895}

896

900 assert(Parent && "We should only create an implicit global module fragment "

901 "in a module purview");

902

903

904

905 auto *Result = new (ModulesAlloc.Allocate())

907 false, false, NumCreatedModules++);

910}

911

915 auto *Result = new (ModulesAlloc.Allocate()) Module(

917 true, NumCreatedModules++);

920}

921

924 auto *Result = new (ModulesAlloc.Allocate())

926 false, NumCreatedModules++);

928

929

930 for (auto &Submodule : PendingSubmodules)

931 Submodule->setParent(Result);

932 PendingSubmodules.clear();

934}

935

937 StringRef Name) {

938 assert(LangOpts.CurrentModule == Name && "module name mismatch");

939 assert(!Modules[Name] && "redefining existing module");

940

943 Modules[Name] = SourceModule = Result;

944

945

946

947 auto MainFile = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());

948 assert(MainFile && "no input file for module interface");

950

952}

953

955 StringRef Name) {

956 assert(LangOpts.CurrentModule == Name && "module name mismatch");

957

959 "creating implementation module without an interface");

960

961

962

963

964 StringRef IName = ".ImplementationUnit";

965 assert(!Modules[IName] && "multiple implementation units?");

966

969 Modules[IName] = SourceModule = Result;

970

971

972 assert(SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) &&

973 "no input file for module implementation");

974

976}

977

980 assert(LangOpts.CurrentModule == Name && "module name mismatch");

981 assert(!Modules[Name] && "redefining existing module");

982

983 auto *Result = new (ModulesAlloc.Allocate())

985 false, NumCreatedModules++);

987 Modules[Name] = SourceModule = Result;

990}

991

992

993

995 assert(Mod->IsFramework && "Can only infer linking for framework modules");

997 "Can only infer linking for top-level frameworks");

998

999 StringRef FrameworkName(Mod->Name);

1000 FrameworkName.consume_back("_Private");

1002 true));

1003}

1004

1006 bool IsSystem, Module *Parent) {

1007 Attributes Attrs;

1009 return inferFrameworkModule(FrameworkDir, Attrs, Parent);

1010}

1011

1013 Attributes Attrs, Module *Parent) {

1014

1015

1016

1017

1018 StringRef FrameworkDirName =

1019 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);

1020

1021

1022

1023

1026 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);

1027

1028

1030 return Mod;

1031

1033

1034

1035

1036 FileID ModuleMapFID;

1037 if (!Parent) {

1038

1039 bool canInfer = false;

1040 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {

1041

1042 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);

1043 if (auto ParentDir = FileMgr.getOptionalDirectoryRef(Parent)) {

1044

1045

1046 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator

1047 inferred = InferredDirectories.find(*ParentDir);

1048 if (inferred == InferredDirectories.end()) {

1049

1050

1051 bool IsFrameworkDir = Parent.ends_with(".framework");

1054

1055

1057 inferred = InferredDirectories.find(*ParentDir);

1058 }

1059

1060 if (inferred == InferredDirectories.end())

1061 inferred = InferredDirectories.insert(

1062 std::make_pair(*ParentDir, InferredDirectory())).first;

1063 }

1064

1065 if (inferred->second.InferModules) {

1066

1067

1068 StringRef Name = llvm::sys::path::stem(FrameworkDirName);

1069 canInfer =

1070 !llvm::is_contained(inferred->second.ExcludedModules, Name);

1071

1072 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;

1073 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;

1074 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;

1075 Attrs.NoUndeclaredIncludes |=

1076 inferred->second.Attrs.NoUndeclaredIncludes;

1077 ModuleMapFID = inferred->second.ModuleMapFID;

1078 }

1079 }

1080 }

1081

1082

1083 if (!canInfer)

1084 return nullptr;

1085 } else {

1087 }

1088

1089

1090 SmallString<128> UmbrellaName = FrameworkDir.getName();

1091 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");

1093

1094

1095

1096

1097 if (!UmbrellaHeader)

1098 return nullptr;

1099

1100 Module *Result = new (ModulesAlloc.Allocate())

1101 Module(ModuleConstructorTag{}, ModuleName, SourceLocation(), Parent,

1102 true, false, NumCreatedModules++);

1104 if (!Parent) {

1105 if (LangOpts.CurrentModule == ModuleName)

1106 SourceModule = Result;

1107 Modules[ModuleName] = Result;

1108 ModuleScopeIDs[Result] = CurrentModuleScopeID;

1109 }

1110

1111 Result->IsSystem |= Attrs.IsSystem;

1112 Result->IsExternC |= Attrs.IsExternC;

1113 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;

1114 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;

1115 Result->Directory = FrameworkDir;

1116

1117

1118 StringRef RelativePath = UmbrellaName.str().substr(

1119 Result->getTopLevelModule()->Directory->getName().size());

1120 RelativePath = llvm::sys::path::relative_path(RelativePath);

1121

1122

1124 RelativePath);

1125

1126

1128

1129

1130 Result->InferSubmodules = true;

1131 Result->InferExportWildcard = true;

1132

1133

1134 std::error_code EC;

1135 SmallString<128> SubframeworksDirName = FrameworkDir.getName();

1136 llvm::sys::path::append(SubframeworksDirName, "Frameworks");

1137 llvm::sys::path::native(SubframeworksDirName);

1139 for (llvm::vfs::directory_iterator

1140 Dir = FS.dir_begin(SubframeworksDirName, EC),

1141 DirEnd;

1142 Dir != DirEnd && !EC; Dir.increment(EC)) {

1143 if (!StringRef(Dir->path()).ends_with(".framework"))

1144 continue;

1145

1147

1148

1149

1150

1151 StringRef SubframeworkDirName =

1153 bool FoundParent = false;

1154 do {

1155

1156 SubframeworkDirName

1157 = llvm::sys::path::parent_path(SubframeworkDirName);

1158 if (SubframeworkDirName.empty())

1159 break;

1160

1161 if (auto SubDir =

1163 if (*SubDir == FrameworkDir) {

1164 FoundParent = true;

1165 break;

1166 }

1167 }

1168 } while (true);

1169

1170 if (!FoundParent)

1171 continue;

1172

1173

1174 inferFrameworkModule(*SubframeworkDir, Attrs, Result);

1175 }

1176 }

1177

1178

1179

1180 if (Result->isSubFramework())

1182

1184}

1185

1187 Module *ShadowingModule) {

1188

1189

1190 Module *Result = new (ModulesAlloc.Allocate())

1192 IsFramework, false, NumCreatedModules++);

1193 Result->ShadowingModule = ShadowingModule;

1194 Result->markUnavailable(true);

1195 ModuleScopeIDs[Result] = CurrentModuleScopeID;

1196 ShadowModules.push_back(Result);

1197

1199}

1200

1202 Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,

1203 const Twine &PathRelativeToRootModuleDirectory) {

1205 Mod->Umbrella = UmbrellaHeader;

1208 PathRelativeToRootModuleDirectory.str();

1209 UmbrellaDirs[UmbrellaHeader.getDir()] = Mod;

1210

1211

1212 for (const auto &Cb : Callbacks)

1213 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);

1214}

1215

1218 const Twine &PathRelativeToRootModuleDirectory) {

1219 Mod->Umbrella = UmbrellaDir;

1222 PathRelativeToRootModuleDirectory.str();

1223 UmbrellaDirs[UmbrellaDir] = Mod;

1224}

1225

1226void ModuleMap::addUnresolvedHeader(Module *Mod,

1228 bool &NeedsFramework) {

1229

1230

1231 if (resolveAsBuiltinHeader(Mod, Header)) {

1232

1233

1234

1235

1239 }

1240

1241

1242

1243

1244

1247

1248

1250 LazyHeadersByModTime[*Header.ModTime].push_back(Mod);

1251 else

1252 LazyHeadersBySize[*Header.Size].push_back(Mod);

1254 return;

1255 }

1256

1257

1258

1259 resolveHeader(Mod, Header, NeedsFramework);

1260}

1261

1263 auto BySize = LazyHeadersBySize.find(File->getSize());

1264 if (BySize != LazyHeadersBySize.end()) {

1265 for (auto *M : BySize->second)

1267 LazyHeadersBySize.erase(BySize);

1268 }

1269

1270 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());

1271 if (ByModTime != LazyHeadersByModTime.end()) {

1272 for (auto *M : ByModTime->second)

1274 LazyHeadersByModTime.erase(ByModTime);

1275 }

1276}

1277

1279 Module *Mod, std::optional<const FileEntry *> File) const {

1280 bool NeedsFramework = false;

1282 const auto Size = File ? (*File)->getSize() : 0;

1283 const auto ModTime = File ? (*File)->getModificationTime() : 0;

1284

1287 (Header.Size && Header.Size != Size)))

1288 NewHeaders.push_back(Header);

1289 else

1290

1291

1292 const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework);

1293 }

1295}

1296

1300

1302

1303

1304

1305

1306 auto &HeaderList = Headers[HeaderEntry];

1307 if (llvm::is_contained(HeaderList, KH))

1308 return;

1309

1310 HeaderList.push_back(KH);

1312

1313 bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts);

1314 if (!Imported || isCompilingModuleHeader) {

1315

1316

1317 HeaderInfo.MarkFileModuleHeader(HeaderEntry, Role, isCompilingModuleHeader);

1318 }

1319

1320

1321 for (const auto &Cb : Callbacks)

1322 Cb->moduleMapAddHeader(HeaderEntry.getName());

1323}

1324

1328 llvm::DenseMap<const FileEntry *, const modulemap::ModuleMapFile *>::iterator

1329 Known = ParsedModuleMap.find(File);

1330 if (Known != ParsedModuleMap.end())

1331 return Known->second == nullptr;

1332

1333

1334 if (ID.isInvalid()) {

1335 ID = SourceMgr.translateFile(File);

1336 if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) {

1337 auto FileCharacter =

1339 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);

1340 }

1341 }

1342

1343 std::optionalllvm::MemoryBufferRef Buffer = SourceMgr.getBufferOrNone(ID);

1344 if (!Buffer) {

1345 ParsedModuleMap[File] = nullptr;

1346 return true;

1347 }

1348

1349 Diags.Report(diag::remark_mmap_parse) << File.getName();

1350 std::optionalmodulemap::ModuleMapFile MaybeMMF =

1352

1353 if (!MaybeMMF) {

1354 ParsedModuleMap[File] = nullptr;

1355 return true;

1356 }

1357

1358 ParsedModuleMaps.push_back(

1359 std::make_uniquemodulemap::ModuleMapFile(std::move(*MaybeMMF)));

1361 std::vector<const modulemap::ExternModuleDecl *> PendingExternalModuleMaps;

1362 for (const auto &Decl : MMF.Decls) {

1363 std::visit(llvm::makeVisitor(

1365

1366

1367

1368 auto &ModuleDecls =

1369 ParsedModules[StringRef(MD.Id.front().first)];

1370 ModuleDecls.push_back(std::pair(&MMF, &MD));

1371 },

1373 PendingExternalModuleMaps.push_back(&EMD);

1374 }),

1376 }

1377

1379 StringRef FileNameRef = EMD->Path;

1381 if (llvm::sys::path::is_relative(FileNameRef)) {

1382 ModuleMapFileName += Dir.getName();

1383 llvm::sys::path::append(ModuleMapFileName, EMD->Path);

1384 FileNameRef = ModuleMapFileName;

1385 }

1386

1387 if (auto EFile =

1388 SourceMgr.getFileManager().getOptionalFileRef(FileNameRef)) {

1390 ExternModuleLoc);

1391 }

1392 }

1393

1394 ParsedModuleMap[File] = &MMF;

1395

1396 for (const auto &Cb : Callbacks)

1398

1399 return false;

1400}

1401

1404 return {};

1405

1407}

1408

1413

1416 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");

1417 return InferredModuleAllowedBy.find(M)->second;

1418 }

1420}

1421

1426

1429 InferredModuleAllowedBy[M] = ModMapFID;

1430}

1431

1432std::error_code

1434 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});

1435

1436

1437

1438 if (llvm::sys::path::filename(Dir) == "Modules") {

1439 StringRef Parent = llvm::sys::path::parent_path(Dir);

1440 if (Parent.ends_with(".framework"))

1441 Dir = Parent;

1442 }

1443

1444 FileManager &FM = SourceMgr.getFileManager();

1445 auto DirEntry = FM.getDirectoryRef(Dir.empty() ? "." : Dir);

1446 if (!DirEntry)

1447 return llvm::errorToErrorCode(DirEntry.takeError());

1448

1449

1451 if (CanonicalDir != Dir)

1452 llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);

1453

1454

1455

1456

1457

1458

1459

1460 llvm::sys::path::remove_dots(Path);

1461

1462 return std::error_code();

1463}

1464

1467 AdditionalModMaps[M].insert(ModuleMap);

1468}

1469

1471 llvm::errs() << "Modules:";

1472 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),

1473 MEnd = Modules.end();

1474 M != MEnd; ++M)

1475 M->getValue()->print(llvm::errs(), 2);

1476

1477 llvm::errs() << "Headers:";

1478 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();

1479 H != HEnd; ++H) {

1480 llvm::errs() << " \"" << H->first.getName() << "\" -> ";

1482 E = H->second.end();

1483 I != E; ++I) {

1484 if (I != H->second.begin())

1485 llvm::errs() << ",";

1486 llvm::errs() << I->getModule()->getFullModuleName();

1487 }

1488 llvm::errs() << "\n";

1489 }

1490}

1491

1497 if (Export.getPointer() || Export.getInt())

1498 Mod->Exports.push_back(Export);

1499 else

1501 }

1503}

1504

1507 auto Unresolved = std::move(Top->UnresolvedDirectUses);

1508 Top->UnresolvedDirectUses.clear();

1510 Module *DirectUse = resolveModuleId(UDU, Top, Complain);

1511 if (DirectUse)

1512 Top->DirectUses.push_back(DirectUse);

1513 else

1514 Top->UnresolvedDirectUses.push_back(UDU);

1515 }

1516 return !Top->UnresolvedDirectUses.empty();

1517}

1518

1523 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {

1525 Conflict.Other = OtherMod;

1526 Conflict.Message = UC.Message;

1527 Mod->Conflicts.push_back(Conflict);

1528 } else

1530 }

1532}

1533

1534

1535

1536

1537

1538namespace clang {

1541

1544

1545

1546 FileID ModuleMapFID;

1547

1548

1550

1551

1552

1554

1555

1556 bool IsSystem;

1557

1558

1559 bool HadError = false;

1560

1561

1562 Module *ActiveModule = nullptr;

1563

1564

1565

1566

1567

1568

1569

1570

1571

1573

1586

1587

1588

1589

1590

1591 void diagnosePrivateModules(SourceLocation StartLoc);

1592

1593 using Attributes = ModuleMap::Attributes;

1594

1595public:

1599 : SourceMgr(SourceMgr), Diags(Diags), Map(Map),

1600 ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {}

1601

1605};

1606

1607}

1608

1609

1610

1611

1612

1613void ModuleMapLoader::diagnosePrivateModules(SourceLocation StartLoc) {

1614 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,

1615 const Module *M, SourceRange ReplLoc) {

1616 auto D = Diags.Report(ActiveModule->DefinitionLoc,

1617 diag::note_mmap_rename_top_level_private_module);

1618 D << BadName << M->Name;

1620 };

1621

1622 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {

1623 auto const *M = E->getValue();

1624 if (M->Directory != ActiveModule->Directory)

1625 continue;

1626

1627 SmallString<128> FullName(ActiveModule->getFullModuleName());

1628 if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private"))

1629 continue;

1630 SmallString<128> FixedPrivModDecl;

1631 SmallString<128> Canonical(M->Name);

1632 Canonical.append("_Private");

1633

1634

1635 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&

1636 M->Name == ActiveModule->Parent->Name) {

1637 Diags.Report(ActiveModule->DefinitionLoc,

1638 diag::warn_mmap_mismatched_private_submodule)

1639 << FullName;

1640

1641 SourceLocation FixItInitBegin = CurrModuleDeclLoc;

1643 FixItInitBegin = StartLoc;

1644

1645 if (ActiveModule->Parent->IsFramework)

1646 FixedPrivModDecl.append("framework ");

1647 FixedPrivModDecl.append("module ");

1648 FixedPrivModDecl.append(Canonical);

1649

1650 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,

1651 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));

1652 continue;

1653 }

1654

1655

1656 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&

1657 ActiveModule->Name != Canonical) {

1658 Diags.Report(ActiveModule->DefinitionLoc,

1659 diag::warn_mmap_mismatched_private_module_name)

1660 << ActiveModule->Name;

1661 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,

1662 SourceRange(ActiveModule->DefinitionLoc));

1663 }

1664 }

1665}

1666

1668 if (MD.Id.front().first == "*")

1669 return handleInferredModuleDecl(MD);

1670

1671 CurrModuleDeclLoc = MD.Location;

1672

1673 Module *PreviousActiveModule = ActiveModule;

1674 if (MD.Id.size() > 1) {

1675

1676

1677 ActiveModule = nullptr;

1678 const Module *TopLevelModule = nullptr;

1679 for (unsigned I = 0, N = MD.Id.size() - 1; I != N; ++I) {

1681 Map.lookupModuleQualified(MD.Id[I].first, ActiveModule)) {

1682 if (I == 0)

1683 TopLevelModule = Next;

1684 ActiveModule = Next;

1685 continue;

1686 }

1687

1688 Diags.Report(MD.Id[I].second, diag::err_mmap_missing_parent_module)

1689 << MD.Id[I].first << (ActiveModule != nullptr)

1690 << (ActiveModule

1691 ? ActiveModule->getTopLevelModule()->getFullModuleName()

1692 : "");

1693 HadError = true;

1694 }

1695

1696 if (TopLevelModule &&

1697 ModuleMapFID != Map.getContainingModuleMapFileID(TopLevelModule)) {

1698 assert(ModuleMapFID !=

1699 Map.getModuleMapFileIDForUniquing(TopLevelModule) &&

1700 "submodule defined in same file as 'module *' that allowed its "

1701 "top-level module");

1702 Map.addAdditionalModuleMapFile(

1703 TopLevelModule, *SourceMgr.getFileEntryRefForID(ModuleMapFID));

1704 }

1705 }

1706

1707 StringRef ModuleName = MD.Id.back().first;

1708 SourceLocation ModuleNameLoc = MD.Id.back().second;

1709

1710

1711 Module *ShadowingModule = nullptr;

1712 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {

1713

1714

1715

1716

1717 bool LoadedFromASTFile = Existing->IsFromModuleFile;

1718

1719 bool Inferred = Existing->IsInferred;

1720

1721

1722

1723

1724

1725

1726

1727

1728

1729

1730

1731

1732

1733

1734

1735 bool PartOfFramework = MD.Framework || Existing->isPartOfFramework();

1736

1737

1738 bool ParsedAsMainInput =

1740 Map.LangOpts.CurrentModule == ModuleName &&

1741 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=

1742 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;

1743

1744

1745 bool SameModuleDecl = ModuleNameLoc == Existing->DefinitionLoc;

1746 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput ||

1747 SameModuleDecl) {

1748 ActiveModule = PreviousActiveModule;

1749

1750 return;

1751 }

1752

1753 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {

1754 ShadowingModule = Existing;

1755 } else {

1756

1757 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)

1758 << ModuleName;

1759 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);

1760 HadError = true;

1761 return;

1762 }

1763 }

1764

1765

1766 if (ShadowingModule) {

1767 ActiveModule =

1768 Map.createShadowedModule(ModuleName, MD.Framework, ShadowingModule);

1769 } else {

1770 ActiveModule = Map.findOrCreateModuleFirst(ModuleName, ActiveModule,

1772 }

1773

1774 ActiveModule->DefinitionLoc = ModuleNameLoc;

1776 ActiveModule->IsSystem = true;

1778 ActiveModule->IsExternC = true;

1780 ActiveModule->NoUndeclaredIncludes = true;

1781 ActiveModule->Directory = Directory;

1782

1783 StringRef MapFileName(

1784 SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());

1785 if (MapFileName.ends_with("module.private.modulemap") ||

1786 MapFileName.ends_with("module_private.map")) {

1787 ActiveModule->ModuleMapIsPrivate = true;

1788 }

1789

1790

1791

1792

1793 SourceLocation StartLoc =

1794 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());

1795 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&

1796 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,

1797 StartLoc) &&

1798 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,

1799 StartLoc) &&

1800 ActiveModule->ModuleMapIsPrivate)

1801 diagnosePrivateModules(MD.Location);

1802

1804 std::visit(

1805 llvm::makeVisitor(

1806 [&](const modulemap::RequiresDecl &RD) { handleRequiresDecl(RD); },

1807 [&](const modulemap::HeaderDecl &HD) { handleHeaderDecl(HD); },

1808 [&](const modulemap::UmbrellaDirDecl &UDD) {

1809 handleUmbrellaDirDecl(UDD);

1810 },

1811 [&](const modulemap::ModuleDecl &MD) { handleModuleDecl(MD); },

1812 [&](const modulemap::ExportDecl &ED) { handleExportDecl(ED); },

1813 [&](const modulemap::ExportAsDecl &EAD) {

1814 handleExportAsDecl(EAD);

1815 },

1816 [&](const modulemap::ExternModuleDecl &EMD) {

1817 handleExternModuleDecl(EMD);

1818 },

1819 [&](const modulemap::UseDecl &UD) { handleUseDecl(UD); },

1820 [&](const modulemap::LinkDecl &LD) { handleLinkDecl(LD); },

1821 [&](const modulemap::ConfigMacrosDecl &CMD) {

1822 handleConfigMacros(CMD);

1823 },

1824 [&](const modulemap::ConflictDecl &CD) { handleConflict(CD); },

1825 [&](const modulemap::ExcludeDecl &ED) {

1826 Diags.Report(ED.Location, diag::err_mmap_expected_member);

1827 }),

1829 }

1830

1831

1832

1833 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&

1834 ActiveModule->LinkLibraries.empty())

1836

1837

1838

1839 if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&

1840 ActiveModule->Parent) {

1841 ActiveModule->getTopLevelModule()->markUnavailable(false);

1842 ActiveModule->getTopLevelModule()->MissingHeaders.append(

1843 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());

1844 }

1845

1846

1847 ActiveModule = PreviousActiveModule;

1848}

1849

1850void ModuleMapLoader::handleExternModuleDecl(

1852 StringRef FileNameRef = EMD.Path;

1853 SmallString<128> ModuleMapFileName;

1854 if (llvm::sys::path::is_relative(FileNameRef)) {

1855 ModuleMapFileName += Directory.getName();

1856 llvm::sys::path::append(ModuleMapFileName, EMD.Path);

1857 FileNameRef = ModuleMapFileName;

1858 }

1859 if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))

1860 Map.parseAndLoadModuleMapFile(

1861 *File, IsSystem,

1862 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd

1863 ? Directory

1864 : File->getDir(),

1865 FileID(), nullptr, EMD.Location);

1866}

1867

1868

1869

1870

1871

1872

1873

1874

1875

1876

1877

1878

1879

1880

1881

1882

1884 bool &IsRequiresExcludedHack) {

1885 if (Feature == "excluded" &&

1888 IsRequiresExcludedHack = true;

1889 return false;

1891 return false;

1892 }

1893

1894 return true;

1895}

1896

1898

1899 for (const modulemap::RequiresFeature &RF : RD.Features) {

1900 bool IsRequiresExcludedHack = false;

1901 bool ShouldAddRequirement =

1903

1904 if (IsRequiresExcludedHack)

1905 UsesRequiresExcludedHack.insert(ActiveModule);

1906

1907 if (ShouldAddRequirement) {

1908

1910 *Map.Target);

1911 }

1912 }

1913}

1914

1916

1918

1923 }

1924

1927

1928 if (UsesRequiresExcludedHack.count(ActiveModule)) {

1929

1930

1932 }

1933

1934 Module::UnresolvedHeaderDirective Header;

1938 Header.Kind = Map.headerRoleToKind(Role);

1939

1940

1942 !std::holds_alternativestd::monostate(ActiveModule->Umbrella)) {

1943 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)

1944 << ActiveModule->getFullModuleName();

1945 HadError = true;

1946 return;

1947 }

1948

1949 if (HD.Size)

1953

1954 bool NeedsFramework = false;

1955

1956

1957

1958 if (!Map.LangOpts.BuiltinHeadersInSystemModules ||

1960 ActiveModule->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}))

1961 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);

1962

1963 if (NeedsFramework)

1964 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)

1965 << ActiveModule->getFullModuleName()

1967}

1968

1973

1974void ModuleMapLoader::handleUmbrellaDirDecl(

1976 std::string DirName = std::string(UDD.Path);

1977 std::string DirNameAsWritten = DirName;

1978

1979

1980 if (!std::holds_alternativestd::monostate(ActiveModule->Umbrella)) {

1981 Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)

1982 << ActiveModule->getFullModuleName();

1983 HadError = true;

1984 return;

1985 }

1986

1987

1989 if (llvm::sys::path::is_absolute(DirName)) {

1990 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);

1991 } else {

1992 SmallString<128> PathName;

1993 PathName = Directory.getName();

1994 llvm::sys::path::append(PathName, DirName);

1995 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName);

1996 }

1997

1998 if (!Dir) {

1999 Diags.Report(UDD.Location, diag::warn_mmap_umbrella_dir_not_found)

2000 << DirName;

2001 return;

2002 }

2003

2004 if (UsesRequiresExcludedHack.count(ActiveModule)) {

2005

2006

2007

2008

2009 std::error_code EC;

2010 SmallVector<Module::Header, 6> Headers;

2011 llvm::vfs::FileSystem &FS =

2012 SourceMgr.getFileManager().getVirtualFileSystem();

2013 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;

2014 I != E && !EC; I.increment(EC)) {

2015 if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) {

2016 Module::Header Header = {"", std::string(I->path()), *FE};

2017 Headers.push_back(std::move(Header));

2018 }

2019 }

2020

2021

2023

2024 for (auto &Header : Headers)

2026 return;

2027 }

2028

2029 if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {

2030 Diags.Report(UDD.Location, diag::err_mmap_umbrella_clash)

2031 << OwningModule->getFullModuleName();

2032 HadError = true;

2033 return;

2034 }

2035

2036

2037 Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName);

2038}

2039

2042 ActiveModule->UnresolvedExports.push_back(Unresolved);

2043}

2044

2046 const auto &ModName = EAD.Id.front();

2047

2048 if (!ActiveModule->ExportAsModule.empty()) {

2049 if (ActiveModule->ExportAsModule == ModName.first) {

2050 Diags.Report(ModName.second, diag::warn_mmap_redundant_export_as)

2051 << ActiveModule->Name << ModName.first;

2052 } else {

2053 Diags.Report(ModName.second, diag::err_mmap_conflicting_export_as)

2054 << ActiveModule->Name << ActiveModule->ExportAsModule

2055 << ModName.first;

2056 }

2057 }

2058

2059 ActiveModule->ExportAsModule = ModName.first;

2060 Map.addLinkAsDependency(ActiveModule);

2061}

2062

2064 if (ActiveModule->Parent)

2065 Diags.Report(UD.Location, diag::err_mmap_use_decl_submodule);

2066 else

2067 ActiveModule->UnresolvedDirectUses.push_back(UD.Id);

2068}

2069

2071 ActiveModule->LinkLibraries.push_back(

2072 Module::LinkLibrary(std::string{LD.Library}, LD.Framework));

2073}

2074

2075void ModuleMapLoader::handleConfigMacros(

2077 if (ActiveModule->Parent) {

2078 Diags.Report(CMD.Location, diag::err_mmap_config_macro_submodule);

2079 return;

2080 }

2081

2082

2083

2085 ActiveModule->ConfigMacrosExhaustive = true;

2086 }

2087 ActiveModule->ConfigMacros.insert(ActiveModule->ConfigMacros.end(),

2089}

2090

2092 Module::UnresolvedConflict Conflict;

2093

2094 Conflict.Id = CD.Id;

2096

2097

2098 ActiveModule->UnresolvedConflicts.push_back(std::move(Conflict));

2099}

2100

2101void ModuleMapLoader::handleInferredModuleDecl(

2103 SourceLocation StarLoc = MD.Id.front().second;

2104

2105

2106 if (!ActiveModule && !MD.Framework) {

2107 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);

2108 return;

2109 }

2110

2111 if (ActiveModule) {

2112

2113 if (ActiveModule->IsAvailable && !ActiveModule->getEffectiveUmbrellaDir()) {

2114 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);

2115 return;

2116 }

2117

2118

2119 if (ActiveModule->InferSubmodules) {

2120 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);

2121 if (ActiveModule->InferredSubmoduleLoc.isValid())

2122 Diags.Report(ActiveModule->InferredSubmoduleLoc,

2123 diag::note_mmap_prev_definition);

2124 return;

2125 }

2126

2127

2129 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);

2130 return;

2131 }

2133 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);

2134 return;

2135 }

2136

2137 if (ActiveModule) {

2138

2139 ActiveModule->InferSubmodules = true;

2140 ActiveModule->InferredSubmoduleLoc = StarLoc;

2141 ActiveModule->InferExplicitSubmodules = MD.Explicit;

2142 } else {

2143

2144 auto &InfDir = Map.InferredDirectories[Directory];

2145 InfDir.InferModules = true;

2146 InfDir.Attrs = MD.Attrs;

2147 InfDir.ModuleMapFID = ModuleMapFID;

2148

2149 }

2150

2152 std::visit(

2153 llvm::makeVisitor(

2154 [&](const auto &Other) {

2155 Diags.Report(Other.Location,

2156 diag::err_mmap_expected_inferred_member)

2157 << (ActiveModule != nullptr);

2158 },

2159 [&](const modulemap::ExcludeDecl &ED) {

2160

2161 if (ActiveModule) {

2163 diag::err_mmap_expected_inferred_member)

2164 << (ActiveModule != nullptr);

2165 HadError = true;

2166 return;

2167 }

2168 Map.InferredDirectories[Directory].ExcludedModules.emplace_back(

2169 ED.Module);

2170 },

2171 [&](const modulemap::ExportDecl &ED) {

2172

2173 if (!ActiveModule) {

2175 diag::err_mmap_expected_inferred_member)

2176 << (ActiveModule != nullptr);

2177 HadError = true;

2178 return;

2179 }

2180

2181 if (ED.Wildcard && ED.Id.size() == 0)

2182 ActiveModule->InferExportWildcard = true;

2183 else

2184 Diags.Report(ED.Id.front().second,

2185 diag::err_mmap_expected_export_wildcard);

2186 }),

2188 }

2189}

2190

2192 handleModuleDecl(MD);

2193 return HadError;

2194}

2195

2198 handleExternModuleDecl(EMD);

2199 return HadError;

2200}

2201

2204 for (const auto &Decl : MMF.Decls) {

2205 std::visit(

2206 llvm::makeVisitor(

2209 handleExternModuleDecl(EMD);

2210 }),

2212 }

2213 return HadError;

2214}

2215

2217 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);

2218 if (Known != Modules.end())

2219 return Known->getValue();

2220

2221 auto ParsedMod = ParsedModules.find(Name);

2222 if (ParsedMod == ParsedModules.end())

2223 return nullptr;

2224

2225 Diags.Report(diag::remark_mmap_load_module) << Name;

2226

2227 for (const auto &ModuleDecl : ParsedMod->second) {

2232 return nullptr;

2233 }

2234

2236}

2237

2240 unsigned *Offset,

2242 assert(Target && "Missing target information");

2243 llvm::DenseMap<const FileEntry *, bool>::iterator Known =

2244 LoadedModuleMap.find(File);

2245 if (Known != LoadedModuleMap.end())

2246 return Known->second;

2247

2248

2249 if (ID.isInvalid()) {

2250 ID = SourceMgr.translateFile(File);

2251

2252

2253

2254

2255 if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) {

2256 auto FileCharacter =

2258 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);

2259 }

2260 }

2261

2262 assert(Target && "Missing target information");

2263 std::optionalllvm::MemoryBufferRef Buffer = SourceMgr.getBufferOrNone(ID);

2264 if (!Buffer)

2265 return LoadedModuleMap[File] = true;

2266 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&

2267 "invalid buffer offset");

2268

2269 std::optionalmodulemap::ModuleMapFile MMF =

2271 bool Result = false;

2272 if (MMF) {

2273 Diags.Report(diag::remark_mmap_load) << File.getName();

2274 ModuleMapLoader Loader(SourceMgr, Diags, *this, ID, Dir, IsSystem);

2276 }

2278

2279

2280

2281 for (const auto &Cb : Callbacks)

2282 Cb->moduleMapFileRead(MMF ? MMF->Start : SourceLocation(), File, IsSystem);

2283

2285}

Defines the Diagnostic-related interfaces.

Defines the clang::FileManager interface and associated types.

std::shared_ptr< TokenRole > Role

A token can have a special role that can carry extra information about the token's formatting.

FormatToken * Next

The next token in the unwrapped line.

#define ALIAS(NAME, TOK, FLAGS)

#define KEYWORD(NAME, FLAGS)

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::LangOptions interface.

static bool isBuiltinHeaderName(StringRef FileName)

Determine whether the given file name is the name of a builtin header, supplied by Clang to replace,...

Definition ModuleMap.cpp:252

static bool isBuiltInModuleName(StringRef ModuleName)

Determine whether the given module name is the name of a builtin module that is cyclic with a system ...

Definition ModuleMap.cpp:272

static Module * getTopLevelOrNull(Module *M)

Definition ModuleMap.cpp:481

static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::KnownHeader Header)

Definition ModuleMap.cpp:460

static void inferFrameworkLink(Module *Mod)

For a framework module, infer the framework against which we should link.

Definition ModuleMap.cpp:994

static StringRef sanitizeFilenameAsIdentifier(StringRef Name, SmallVectorImpl< char > &Buffer)

"Sanitize" a filename so that it can be used as an identifier.

Definition ModuleMap.cpp:368

static void appendSubframeworkPaths(Module *Mod, SmallVectorImpl< char > &Path)

Append to Paths the set of paths needed to get to the subframework in which the given module lives.

Definition ModuleMap.cpp:156

static bool shouldAddRequirement(Module *M, StringRef Feature, bool &IsRequiresExcludedHack)

Whether to add the requirement Feature to the module M.

Definition ModuleMap.cpp:1883

static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, const ModuleMap::KnownHeader &Old)

Definition ModuleMap.cpp:567

static bool compareModuleHeaders(const Module::Header &A, const Module::Header &B)

Definition ModuleMap.cpp:1969

Defines the clang::Module class, which describes a module in the source code.

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

Decl - This represents one declaration (or definition), e.g.

Concrete class used by the front-end to report problems and issues.

A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...

StringRef getName() const

A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...

StringRef getName() const

The name of this FileEntry.

DirectoryEntryRef getDir() const

Cached information about one file (either on disk or in the virtual file system).

An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...

Implements support for file system lookup, file system caching, and directory search management.

llvm::vfs::FileSystem & getVirtualFileSystem() const

OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)

Get a FileEntryRef if it exists, without doing anything on error.

StringRef getCanonicalName(DirectoryEntryRef Dir)

Retrieve the canonical name for a given directory.

llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)

Lookup, cache, and verify the specified directory (real or virtual).

OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)

Get a DirectoryEntryRef if it exists, without doing anything on error.

static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)

Create a code modification hint that replaces the given source range with the given code string.

@ CMK_ModuleMap

Compiling a module from a module map.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

Required to construct a Module.

bool loadExternModuleDecl(const modulemap::ExternModuleDecl &EMD)

Definition ModuleMap.cpp:2196

ModuleMapLoader(SourceManager &SourceMgr, DiagnosticsEngine &Diags, ModuleMap &Map, FileID ModuleMapFID, DirectoryEntryRef Directory, bool IsSystem)

Definition ModuleMap.cpp:1596

bool parseAndLoadModuleMapFile(const modulemap::ModuleMapFile &MMF)

Definition ModuleMap.cpp:2202

bool loadModuleDecl(const modulemap::ModuleDecl &MD)

Definition ModuleMap.cpp:2191

Module * createShadowedModule(StringRef Name, bool IsFramework, Module *ShadowingModule)

Create a new top-level module that is shadowed by ShadowingModule.

Definition ModuleMap.cpp:1186

bool resolveExports(Module *Mod, bool Complain)

Resolve all of the unresolved exports in the given module.

Definition ModuleMap.cpp:1492

void addLinkAsDependency(Module *Mod)

Make module to use export_as as the link dependency name if enough information is available or add it...

Definition ModuleMap.cpp:62

friend class ModuleMapLoader

void dump()

Dump the contents of the module map, for debugging purposes.

Definition ModuleMap.cpp:1470

std::pair< Module *, bool > findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)

Find a new module or submodule, or create it if it does not already exist.

Definition ModuleMap.cpp:854

void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)

Sets the umbrella directory of the given module to the given directory.

Definition ModuleMap.cpp:1216

void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, FileEntryRef File)

Reports errors if a module must not include a specific file.

Definition ModuleMap.cpp:485

void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap)

Definition ModuleMap.cpp:1465

OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const

Definition ModuleMap.cpp:1410

static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)

Convert a header role to a kind.

Definition ModuleMap.cpp:69

Module * findModule(StringRef Name) const

Retrieve a module with the given name.

Definition ModuleMap.cpp:813

bool parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())

Load the given module map file, and record any modules we encounter.

Definition ModuleMap.cpp:2238

KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)

Retrieve the module that owns the given header file, if any.

Definition ModuleMap.cpp:595

Module * createHeaderUnit(SourceLocation Loc, StringRef Name, Module::Header H)

Create a C++20 header unit.

Definition ModuleMap.cpp:978

static bool isModular(ModuleHeaderRole Role)

Check if the header with the given role is a modular one.

Definition ModuleMap.cpp:102

bool resolveConflicts(Module *Mod, bool Complain)

Resolve all of the unresolved conflicts in the given module.

Definition ModuleMap.cpp:1519

bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const

Determine whether the given header is unavailable as part of the specified module.

Definition ModuleMap.cpp:719

void resolveHeaderDirectives(const FileEntry *File) const

Resolve all lazy header directives for the specified file.

Definition ModuleMap.cpp:1262

ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const

Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...

Definition ModuleMap.cpp:706

OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const

Definition ModuleMap.cpp:1423

bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, Module *Module) const

Definition ModuleMap.cpp:409

Module * createModuleForImplementationUnit(SourceLocation Loc, StringRef Name)

Create a new module for a C++ module implementation unit.

Definition ModuleMap.cpp:954

ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)

Construct a new module map.

Definition ModuleMap.cpp:352

std::error_code canonicalizeModuleMapPath(SmallVectorImpl< char > &Path)

Canonicalize Path in a manner suitable for a module map file.

Definition ModuleMap.cpp:1433

FileID getModuleMapFileIDForUniquing(const Module *M) const

Get the module map file that (along with the module name) uniquely identifies this module.

Definition ModuleMap.cpp:1414

void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)

Definition ModuleMap.cpp:1427

void setUmbrellaHeaderAsWritten(Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)

Sets the umbrella header of the given module to the given header.

Definition ModuleMap.cpp:1201

Module * findOrCreateModuleFirst(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)

Call ModuleMap::findOrCreateModule and throw away the information whether the module was found or cre...

Module * lookupModuleUnqualified(StringRef Name, Module *Context) const

Retrieve a module with the given name using lexical name lookup, starting at the given context.

Definition ModuleMap.cpp:837

bool isBuiltinHeader(FileEntryRef File)

Is this a compiler builtin header?

Definition ModuleMap.cpp:404

Module * createModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)

Create new submodule, assuming it does not exist.

Definition ModuleMap.cpp:867

bool isHeaderInUnavailableModule(FileEntryRef Header) const

Determine whether the given header is part of a module marked 'unavailable'.

Definition ModuleMap.cpp:715

FileID getContainingModuleMapFileID(const Module *Module) const

Retrieve the module map file containing the definition of the given module.

Definition ModuleMap.cpp:1402

~ModuleMap()

Destroy the module map.

bool parseModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef Dir, FileID ID=FileID(), SourceLocation ExternModuleLoc=SourceLocation())

Parse a module map without creating clang::Module instances.

Definition ModuleMap.cpp:1325

Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent=nullptr)

Create a global module fragment for a C++ module unit.

Definition ModuleMap.cpp:884

void setTarget(const TargetInfo &Target)

Set the target information.

Definition ModuleMap.cpp:361

Module * lookupModuleQualified(StringRef Name, Module *Context) const

Retrieve a module with the given name within the given context, using direct (qualified) name lookup.

Definition ModuleMap.cpp:847

void resolveLinkAsDependencies(Module *Mod)

Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...

Definition ModuleMap.cpp:51

ModuleHeaderRole

Flags describing the role of a module header.

@ PrivateHeader

This header is included but private.

@ ExcludedHeader

This header is explicitly excluded from the module.

@ NormalHeader

This header is normally included in the module.

@ TextualHeader

This header is part of the module (for layering purposes) but should be textually included.

Module * createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name)

Create a new module for a C++ module interface unit.

Definition ModuleMap.cpp:936

void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false)

Adds this header to the given module.

Definition ModuleMap.cpp:1297

Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)

Create a global module fragment for a C++ module interface unit.

Definition ModuleMap.cpp:913

Module * findOrInferSubmodule(Module *Parent, StringRef Name)

Definition ModuleMap.cpp:821

ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)

Retrieve all the modules that contain the given header file.

Definition ModuleMap.cpp:694

Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent)

Definition ModuleMap.cpp:898

Module * createModuleUnitWithKind(SourceLocation Loc, StringRef Name, Module::ModuleKind Kind)

Create a new C++ module with the specified kind, and reparent any pending global module fragment(s) t...

Definition ModuleMap.cpp:922

Module * findOrLoadModule(StringRef Name)

Definition ModuleMap.cpp:2216

static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)

Convert a header kind to a role. Requires Kind to not be HK_Excluded.

Definition ModuleMap.cpp:86

bool resolveUses(Module *Mod, bool Complain)

Resolve all of the unresolved uses in the given module.

Definition ModuleMap.cpp:1505

Describes a module or submodule.

SmallVector< ExportDecl, 2 > Exports

The set of export declarations.

bool isForBuilding(const LangOptions &LangOpts) const

Determine whether this module can be built in this compilation.

std::variant< std::monostate, FileEntryRef, DirectoryEntryRef > Umbrella

The umbrella header or directory.

unsigned InferSubmodules

Whether we should infer submodules for this module based on the headers.

Module * findSubmodule(StringRef Name) const

Find the submodule with the given name.

bool directlyUses(const Module *Requested)

Determine whether this module has declared its intention to directly use another module.

void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const

Print the module map for this module to the given stream.

SourceLocation DefinitionLoc

The location of the module definition.

SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders

Headers that are mentioned in the module map file but could not be found on the file system.

Module * Parent

The parent of this module.

void markUnavailable(bool Unimportable)

Mark this module and all of its submodules as unavailable.

SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders

Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...

bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const

Whether the full name of this module is equal to joining nameParts with "."s.

unsigned IsInferred

Whether this is an inferred submodule (module * { ... }).

unsigned IsSystem

Whether this is a "system" module (which assumes that all headers in it are system headers).

std::string Name

The name of this module.

bool isSubFramework() const

Determine whether this module is a subframework of another framework.

llvm::SmallVector< LinkLibrary, 2 > LinkLibraries

The set of libraries or frameworks to link against when an entity from this module is used.

SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports

The set of export declarations that have yet to be resolved.

void addHeader(HeaderKind HK, Header H)

std::string UmbrellaRelativeToRootModuleDirectory

OptionalDirectoryEntryRef Directory

The build directory of this module.

ArrayRef< Header > getHeaders(HeaderKind HK) const

unsigned InferExportWildcard

Whether, when inferring submodules, the inferr submodules should export all modules they import (e....

std::vector< UnresolvedConflict > UnresolvedConflicts

The list of conflicts for which the module-id has not yet been resolved.

bool isSubModuleOf(const Module *Other) const

Check if this module is a (possibly transitive) submodule of Other.

bool isPartOfFramework() const

Determine whether this module is a part of a framework, either because it is a framework module or be...

bool isAvailable() const

Determine whether this module is available for use within the current translation unit.

llvm::PointerIntPair< Module *, 1, bool > ExportDecl

Describes an exported module.

@ ModuleImplementationUnit

This is a C++20 module implementation unit.

@ ImplicitGlobalModuleFragment

This is an implicit fragment of the global module which contains only language linkage declarations (...

@ ModuleInterfaceUnit

This is a C++20 module interface unit.

@ ModuleHeaderUnit

This is a C++20 header unit.

@ PrivateModuleFragment

This is the private module fragment within some C++ module.

@ ExplicitGlobalModuleFragment

This is the explicit Global Module Fragment of a modular TU.

unsigned IsFramework

Whether this is a framework module.

std::string ExportAsModule

The module through which entities defined in this module will eventually be exposed,...

std::string getFullModuleName(bool AllowStringLiterals=false) const

Retrieve the full name of this module, including the path from its top-level module.

std::string UmbrellaAsWritten

The name of the umbrella entry, as written in the module map.

unsigned InferExplicitSubmodules

Whether, when inferring submodules, the inferred submodules should be explicit.

Module * getTopLevelModule()

Retrieve the top-level module for this (sub)module, which may be this module.

OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const

Get the effective umbrella directory for this module: either the one explicitly written in the module...

bool UseExportAsModuleLinkName

Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...

std::vector< Conflict > Conflicts

The list of conflicts.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

This class handles loading and caching of source files into memory.

Exposes information about the current target.

Defines the clang::TargetInfo interface.

unsigned kind

All of the diagnostics that can be emitted by the frontend.

bool Sub(InterpState &S, CodePtr OpPC)

std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl

All declarations that can appear in a module declaration.

std::optional< ModuleMapFile > parseModuleMap(FileID ID, clang::DirectoryEntryRef Dir, SourceManager &SM, DiagnosticsEngine &Diags, bool IsSystem, unsigned *Offset)

Parse a module map file into an in memory representation.

The JSON file list parser is used to communicate input to InstallAPI.

CustomizableOptional< FileEntryRef > OptionalFileEntryRef

LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)

SmallVector< std::pair< std::string, SourceLocation >, 2 > ModuleId

Describes the name of a module.

@ Private

'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...

LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)

Return true if this is a valid ASCII identifier.

@ Module

Module linkage, which indicates that the entity can be referred to from other translation units withi...

@ Result

The result type of a method or function.

LLVM_READONLY bool isDigit(unsigned char c)

Return true if this character is an ASCII digit: [0-9].

@ Keyword

The name has been typo-corrected to a keyword.

CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef

@ Other

Other implicit parameter.

unsigned IsExternC

Whether this is an extern "C" module.

unsigned IsSystem

Whether this is a system module.

unsigned NoUndeclaredIncludes

Whether files in this module can only include non-modular headers and headers from used modules.

A conflict between two modules.

Module * Other

The module that this module conflicts with.

std::string Message

The message provided to the user when there is a conflict.

A library or framework to link against when an entity from this module is used.

std::string Message

The message provided to the user when there is a conflict.

ModuleId Id

The (unresolved) module id.

Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...

std::vector< StringRef > Macros

ModuleAttributes Attrs

Points to the first keyword in the decl.

std::vector< Decl > Decls

Represents the parsed form of a module map file.

std::vector< TopLevelDecl > Decls

FileID ID

The FileID used to parse this module map. This is always a local ID.

OptionalDirectoryEntryRef Dir

The directory in which the module map was discovered.

std::vector< RequiresFeature > Features