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

1

2

3

4

5

6

7

8

9

10

11

12

13

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

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

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

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

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

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

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

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

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

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

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

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

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

43#include

44#include

45#include

46#include

47#include

48#include

49#include <system_error>

50#include

51

52using namespace clang;

53

54void ModuleMapCallbacks::anchor() {}

55

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

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

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

61 if (M)

62 M->UseExportAsModuleLinkName = true;

63 }

64 }

65}

66

70 else

72}

73

75 switch ((int)Role) {

86 }

87 llvm_unreachable("unknown header role");

88}

89

92 switch ((int)Kind) {

103 }

104 llvm_unreachable("unknown header kind");

105}

106

109}

110

112ModuleMap::resolveExport(Module *Mod,

114 bool Complain) const {

115

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

119 }

120

121

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

123 if (!Context)

124 return {};

125

127}

128

130 bool Complain) const {

131

133 if (!Context) {

134 if (Complain)

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

137

138 return nullptr;

139 }

140

141

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

144 if (!Sub) {

145 if (Complain)

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

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

149

150 return nullptr;

151 }

152

153 Context = Sub;

154 }

155

156 return Context;

157}

158

159

160

163

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

167 Paths.push_back(Mod->Name);

168 }

169

170 if (Paths.empty())

171 return;

172

173

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

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

176}

177

181

184

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

190 return std::nullopt;

191 return *File;

192 };

193

195 unsigned FullPathLength = FullPathName.size();

197 unsigned RelativePathLength = RelativePathName.size();

198

199

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

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

202 if (auto File = GetFile(FullPathName))

204

205

206

207

208

209

210

212 RelativePathName.clear();

213 else

214 RelativePathName.resize(RelativePathLength);

215 FullPathName.resize(FullPathLength);

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

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

219 return GetFile(FullPathName);

220 };

221

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

223 RelativePathName.clear();

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

225 return GetFile(Header.FileName);

226 }

227

229 return GetFrameworkFile();

230

231

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

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

234 auto NormalHdrFile = GetFile(FullPathName);

235

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

237

238

239

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

241 RelativePathName.clear();

242 if (GetFrameworkFile()) {

244 diag::warn_mmap_incomplete_framework_module_declaration)

246 NeedsFramework = true;

247 }

248 return std::nullopt;

249 }

250

251 return NormalHdrFile;

252}

253

254

255

256

258 return llvm::StringSwitch(FileName)

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

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

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

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

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

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

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

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

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

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

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

270 .Default(false);

271}

272

273

274

276 return llvm::StringSwitch(ModuleName)

277 .Case("_Builtin_float", true)

278 .Case("_Builtin_inttypes", true)

279 .Case("_Builtin_iso646", true)

280 .Case("_Builtin_limits", true)

281 .Case("_Builtin_stdalign", true)

282 .Case("_Builtin_stdarg", true)

283 .Case("_Builtin_stdatomic", true)

284 .Case("_Builtin_stdbool", true)

285 .Case("_Builtin_stddef", true)

286 .Case("_Builtin_stdint", true)

287 .Case("_Builtin_stdnoreturn", true)

288 .Case("_Builtin_tgmath", true)

289 .Case("_Builtin_unwind", true)

290 .Default(false);

291}

292

293void ModuleMap::resolveHeader(Module *Mod,

295 bool &NeedsFramework) {

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

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

303 << UmbrellaMod->getFullModuleName();

304 else

305

307 RelativePathName.str());

308 } else {

312 }

314

315

317

318 } else {

319

320

322

323

324

325

328 }

329}

330

331bool ModuleMap::resolveAsBuiltinHeader(

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

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

338 return false;

339

340

341

342

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

347 return false;

348

352 return true;

353}

354

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

359 HeaderInfo(HeaderInfo) {

360 MMapLangOpts.LineComment = true;

361}

362

364

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

367 "Improper target override");

368 this->Target = &Target;

369}

370

371

374 if (Name.empty())

375 return Name;

376

378

379

380 Buffer.clear();

382 Buffer.push_back('_');

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

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

386 Buffer.push_back(Name[I]);

387 else

388 Buffer.push_back('_');

389 }

390

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

392 }

393

394 while (llvm::StringSwitch(Name)

395#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)

396#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)

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

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

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

401 Buffer.push_back('_');

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

403 }

404

405 return Name;

406}

407

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

411}

412

415 return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&

418}

419

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

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

426 return Headers.find(File);

427 }

428 return Known;

429}

430

433 if (UmbrellaDirs.empty())

434 return {};

435

437

438

439

440

441

443

444

445

446 do {

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

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

449 return KnownHeader(KnownDir->second, NormalHeader);

450

451 IntermediateDirs.push_back(*Dir);

452

453

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

455 if (DirName.empty())

456 break;

457

458

460 } while (Dir);

461 return {};

462}

463

467#ifndef NDEBUG

469

470

471

472 bool IsPrivate = false;

476 for (auto Hs : HeaderList)

477 IsPrivate |= llvm::any_of(

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

480 }

481#endif

483}

484

487}

488

490 bool RequestingModuleIsModuleInterface,

493

494

496 return;

497

498 if (RequestingModule) {

499 resolveUses(RequestingModule, false);

501 }

502

503 bool Excluded = false;

505 Module *NotUsed = nullptr;

506

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

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

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

510

512 Excluded = true;

513 continue;

514 }

515

516

519 continue;

520 }

521

522

523

524 if (RequestingModule && LangOpts.ModulesDeclUse &&

527 continue;

528 }

529

530

531 return;

532 }

533

534 Excluded = true;

535 }

536

537

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

541 return;

542 }

543

544

545 if (NotUsed) {

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

548 << NotUsed->Name;

549 return;

550 }

551

552 if (Excluded || isHeaderInUmbrellaDirs(File))

553 return;

554

555

556

557 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {

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

560 } else if (RequestingModule && RequestingModuleIsModuleInterface &&

562

564 diag::warn_non_modular_include_in_framework_module :

565 diag::warn_non_modular_include_in_module;

567 << File.getName();

568 }

569}

570

573

574

575

576

578 return true;

579

580

584

585

589

590

594

595

596 return false;

597}

598

600 bool AllowTextual,

601 bool AllowExcluded) {

604 return {};

605 return R;

606 };

607

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

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

611

613

615 continue;

616

618 return MakeResult(H);

621 }

622 return MakeResult(Result);

623 }

624

625 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));

626}

627

629ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {

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

631

633 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);

634 if (H) {

636

637

638

641 UmbrellaModule = UmbrellaModule->Parent;

642

645

646

647

648

650

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

652

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

659

660

661 UmbrellaDirs[SkippedDir] = Result;

662

663

664

667 }

668

669

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

677

678

679

682 } else {

683

684

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

686 UmbrellaDirs[SkippedDirs[I]] = Result;

687 }

688

690 Headers[File].push_back(Header);

691 return Header;

692 }

693

694 return {};

695}

696

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

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

701 return Known->second;

702

703 if (findOrCreateModuleForHeaderInUmbrellaDir(File))

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

705

706 return {};

707}

708

711

713 auto It = Headers.find(File);

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

715 return {};

716 return It->second;

717}

718

721}

722

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

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

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

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

731 I != E; ++I) {

732

734 continue;

735

736 if (I->isAvailable() &&

737 (!RequestingModule ||

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

739

740

741

742

743

745 continue;

746 return false;

747 }

748 }

749 return true;

750 }

751

754 StringRef DirName = Dir->getName();

755

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

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

759 };

760

761

762

763 do {

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

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

767 if (IsUnavailable(Found))

768 return true;

769

770

771

774 UmbrellaModule->Parent)

775 UmbrellaModule = UmbrellaModule->Parent;

776

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

779

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

785 return false;

786 if (IsUnavailable(Found))

787 return true;

788 }

789

790

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

794 NameBuf);

797 return false;

798 }

799

800 return IsUnavailable(Found);

801 }

802

803 SkippedDirs.push_back(*Dir);

804

805

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

807 if (DirName.empty())

808 break;

809

810

812 } while (Dir);

813

814 return false;

815}

816

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

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

820 return Known->getValue();

821

822 return nullptr;

823}

824

826 if (Module *SubM = Parent->findSubmodule(Name))

827 return SubM;

828 if (Parent->InferSubmodules)

829 return nullptr;

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

832 Parent->InferExplicitSubmodules, 0);

833 Result->InferExplicitSubmodules = Parent->InferExplicitSubmodules;

834 Result->InferSubmodules = Parent->InferSubmodules;

835 Result->InferExportWildcard = Parent->InferExportWildcard;

836 if (Result->InferExportWildcard)

839}

840

842 Module *Context) const {

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

845 return Sub;

846 }

847

849}

850

852 if (!Context)

854

855 return Context->findSubmodule(Name);

856}

857

860 bool IsFramework,

861 bool IsExplicit) {

862

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

865

866

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

869}

870

872 bool IsFramework, bool IsExplicit) {

874 "Creating duplicate submodule");

875

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

878 IsFramework, IsExplicit, NumCreatedModules++);

881 SourceModule = Result;

882 Modules[Name] = Result;

883 ModuleScopeIDs[Result] = CurrentModuleScopeID;

884 }

886}

887

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

892 true, NumCreatedModules++);

894

895

897 PendingSubmodules.emplace_back(Result);

899}

900

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

905 "in a module purview");

906

907

908

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

911 false, false, NumCreatedModules++);

914}

915

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

921 true, NumCreatedModules++);

924}

925

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

930 false, NumCreatedModules++);

932

933

934 for (auto &Submodule : PendingSubmodules)

935 Submodule->setParent(Result);

936 PendingSubmodules.clear();

938}

939

941 StringRef Name) {

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

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

944

947 Modules[Name] = SourceModule = Result;

948

949

950

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

954

956}

957

959 StringRef Name) {

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

961

963 "creating implementation module without an interface");

964

965

966

967

968 StringRef IName = ".ImplementationUnit";

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

970

973 Modules[IName] = SourceModule = Result;

974

975

977 "no input file for module implementation");

978

980}

981

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

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

986

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

989 false, NumCreatedModules++);

991 Modules[Name] = SourceModule = Result;

994}

995

996

997

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

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

1002

1003 StringRef FrameworkName(Mod->Name);

1004 FrameworkName.consume_back("_Private");

1006 true));

1007}

1008

1011 Attributes Attrs;

1013 return inferFrameworkModule(FrameworkDir, Attrs, Parent);

1014}

1015

1018

1019

1020

1021

1022 StringRef FrameworkDirName =

1024

1025

1026

1027

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

1031

1032

1034 return Mod;

1035

1037

1038

1039

1040 FileID ModuleMapFID;

1042

1043 bool canInfer = false;

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

1045

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

1048

1049

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

1051 inferred = InferredDirectories.find(*ParentDir);

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

1053

1054

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

1059 inferred = InferredDirectories.find(*ParentDir);

1060 }

1061

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

1063 inferred = InferredDirectories.insert(

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

1065 }

1066

1067 if (inferred->second.InferModules) {

1068

1069

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

1071 canInfer =

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

1073

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

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

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

1077 Attrs.NoUndeclaredIncludes |=

1078 inferred->second.Attrs.NoUndeclaredIncludes;

1079 ModuleMapFID = inferred->second.ModuleMapFID;

1080 }

1081 }

1082 }

1083

1084

1085 if (!canInfer)

1086 return nullptr;

1087 } else {

1089 }

1090

1091

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

1095

1096

1097

1098

1099 if (!UmbrellaHeader)

1100 return nullptr;

1101

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

1104 true, false, NumCreatedModules++);

1108 SourceModule = Result;

1109 Modules[ModuleName] = Result;

1110 ModuleScopeIDs[Result] = CurrentModuleScopeID;

1111 }

1112

1113 Result->IsSystem |= Attrs.IsSystem;

1114 Result->IsExternC |= Attrs.IsExternC;

1115 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;

1116 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;

1117 Result->Directory = FrameworkDir;

1118

1119

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

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

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

1123

1124

1126 RelativePath);

1127

1128

1130

1131

1132 Result->InferSubmodules = true;

1133 Result->InferExportWildcard = true;

1134

1135

1136 std::error_code EC;

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

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

1141 for (llvm::vfs::directory_iterator

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

1143 DirEnd;

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

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

1146 continue;

1147

1149

1150

1151

1152

1153 StringRef SubframeworkDirName =

1155 bool FoundParent = false;

1156 do {

1157

1158 SubframeworkDirName

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

1160 if (SubframeworkDirName.empty())

1161 break;

1162

1163 if (auto SubDir =

1165 if (*SubDir == FrameworkDir) {

1166 FoundParent = true;

1167 break;

1168 }

1169 }

1170 } while (true);

1171

1172 if (!FoundParent)

1173 continue;

1174

1175

1176 inferFrameworkModule(*SubframeworkDir, Attrs, Result);

1177 }

1178 }

1179

1180

1181

1182 if (Result->isSubFramework())

1184

1186}

1187

1189 Module *ShadowingModule) {

1190

1191

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

1194 IsFramework, false, NumCreatedModules++);

1195 Result->ShadowingModule = ShadowingModule;

1196 Result->markUnavailable(true);

1197 ModuleScopeIDs[Result] = CurrentModuleScopeID;

1198 ShadowModules.push_back(Result);

1199

1201}

1202

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

1205 const Twine &PathRelativeToRootModuleDirectory) {

1207 Mod->Umbrella = UmbrellaHeader;

1210 PathRelativeToRootModuleDirectory.str();

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

1212

1213

1214 for (const auto &Cb : Callbacks)

1215 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);

1216}

1217

1220 const Twine &PathRelativeToRootModuleDirectory) {

1221 Mod->Umbrella = UmbrellaDir;

1224 PathRelativeToRootModuleDirectory.str();

1225 UmbrellaDirs[UmbrellaDir] = Mod;

1226}

1227

1228void ModuleMap::addUnresolvedHeader(Module *Mod,

1230 bool &NeedsFramework) {

1231

1232

1233 if (resolveAsBuiltinHeader(Mod, Header)) {

1234

1235

1236

1237

1241 }

1242

1243

1244

1245

1246

1249

1250

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

1253 else

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

1256 return;

1257 }

1258

1259

1260

1261 resolveHeader(Mod, Header, NeedsFramework);

1262}

1263

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

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

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

1269 LazyHeadersBySize.erase(BySize);

1270 }

1271

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

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

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

1276 LazyHeadersByModTime.erase(ByModTime);

1277 }

1278}

1279

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

1282 bool NeedsFramework = false;

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

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

1286

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

1290 NewHeaders.push_back(Header);

1291 else

1292

1293

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

1295 }

1297}

1298

1302

1304

1305

1306

1307

1308 auto &HeaderList = Headers[HeaderEntry];

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

1310 return;

1311

1312 HeaderList.push_back(KH);

1314

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

1316 if (!Imported || isCompilingModuleHeader) {

1317

1318

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

1320 }

1321

1322

1323 for (const auto &Cb : Callbacks)

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

1325}

1326

1329 return {};

1330

1332}

1333

1337}

1338

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

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

1343 }

1345}

1346

1350}

1351

1354 InferredModuleAllowedBy[M] = ModMapFID;

1355}

1356

1357std::error_code

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

1360

1361

1362

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

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

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

1367 }

1368

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

1371 if (!DirEntry)

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

1373

1374

1376 if (CanonicalDir != Dir)

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

1378

1379

1380

1381

1382

1383

1384

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

1386

1387 return std::error_code();

1388}

1389

1392 AdditionalModMaps[M].insert(ModuleMap);

1393}

1394

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

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

1398 MEnd = Modules.end();

1399 M != MEnd; ++M)

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

1401

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

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

1404 H != HEnd; ++H) {

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

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

1408 I != E; ++I) {

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

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

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

1412 }

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

1414 }

1415}

1416

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

1423 Mod->Exports.push_back(Export);

1424 else

1426 }

1428}

1429

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

1433 Top->UnresolvedDirectUses.clear();

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

1436 if (DirectUse)

1437 Top->DirectUses.push_back(DirectUse);

1438 else

1439 Top->UnresolvedDirectUses.push_back(UDU);

1440 }

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

1442}

1443

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

1450 Conflict.Other = OtherMod;

1451 Conflict.Message = UC.Message;

1452 Mod->Conflicts.push_back(Conflict);

1453 } else

1455 }

1457}

1458

1459

1460

1461

1462

1463namespace clang {

1464

1465

1497

1500 union {

1501

1503

1504

1506 };

1507

1513 }

1514

1516

1519 }

1520

1523 }

1524

1528 }

1529 };

1530

1534

1535

1536

1538

1541

1542

1543 FileID ModuleMapFID;

1544

1545

1547

1548

1549

1551

1552

1553 bool IsSystem;

1554

1555

1556 bool HadError = false;

1557

1558

1559

1560 llvm::BumpPtrAllocator StringData;

1561

1562

1564

1565

1566 Module *ActiveModule = nullptr;

1567

1568

1569

1570

1571

1572

1573

1574

1575

1577

1578

1580

1581

1582

1584

1586 void parseModuleDecl();

1587 void parseExternModuleDecl();

1588 void parseRequiresDecl();

1590 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);

1591 void parseExportDecl();

1592 void parseExportAsDecl();

1593 void parseUseDecl();

1594 void parseLinkDecl();

1595 void parseConfigMacros();

1596 void parseConflict();

1597 void parseInferredModuleDecl(bool Framework, bool Explicit);

1598

1599

1600

1601

1602

1603 void diagnosePrivateModules(SourceLocation ExplicitLoc,

1605

1606 using Attributes = ModuleMap::Attributes;

1607

1608 bool parseOptionalAttributes(Attributes &Attrs);

1609

1610 public:

1615 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),

1616 ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {

1618 consumeToken();

1619 }

1620

1622

1625 };

1626

1627}

1628

1631

1632retry:

1637 switch (LToken.getKind()) {

1638 case tok::raw_identifier: {

1642 Tok.Kind = llvm::StringSwitchMMToken::TokenKind(RI)

1660 break;

1661 }

1662

1663 case tok::comma:

1665 break;

1666

1667 case tok::eof:

1669 break;

1670

1671 case tok::l_brace:

1673 break;

1674

1675 case tok::l_square:

1677 break;

1678

1679 case tok::period:

1681 break;

1682

1683 case tok::r_brace:

1685 break;

1686

1687 case tok::r_square:

1689 break;

1690

1691 case tok:⭐

1693 break;

1694

1695 case tok::exclaim:

1697 break;

1698

1699 case tok::string_literal: {

1701 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);

1702 HadError = true;

1703 goto retry;

1704 }

1705

1706

1710 goto retry;

1711

1712

1713 unsigned Length = StringLiteral.GetStringLength();

1714 char *Saved = StringData.Allocate<char>(Length + 1);

1716 Saved[Length] = 0;

1717

1718

1722 break;

1723 }

1724

1725 case tok::numeric_constant: {

1726

1728 SpellingBuffer.resize(LToken.getLength() + 1);

1729 const char *Start = SpellingBuffer.data();

1730 unsigned Length =

1733 if (StringRef(Start, Length).getAsInteger(0, Value)) {

1735 HadError = true;

1736 goto retry;

1737 }

1738

1741 break;

1742 }

1743

1744 case tok::comment:

1745 goto retry;

1746

1747 case tok::hash:

1748

1749

1750

1751

1752 {

1753 auto NextIsIdent = [&](StringRef Str) -> bool {

1755 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&

1757 };

1758 if (NextIsIdent("pragma") && NextIsIdent("clang") &&

1759 NextIsIdent("module") && NextIsIdent("contents")) {

1761 break;

1762 }

1763 }

1764 [[fallthrough]];

1765

1766 default:

1768 HadError = true;

1769 goto retry;

1770 }

1771

1773}

1774

1776 unsigned braceDepth = 0;

1777 unsigned squareDepth = 0;

1778 do {

1779 switch (Tok.Kind) {

1781 return;

1782

1784 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)

1785 return;

1786

1787 ++braceDepth;

1788 break;

1789

1791 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)

1792 return;

1793

1794 ++squareDepth;

1795 break;

1796

1798 if (braceDepth > 0)

1799 --braceDepth;

1800 else if (Tok.is(K))

1801 return;

1802 break;

1803

1805 if (squareDepth > 0)

1806 --squareDepth;

1807 else if (Tok.is(K))

1808 return;

1809 break;

1810

1811 default:

1812 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))

1813 return;

1814 break;

1815 }

1816

1817 consumeToken();

1818 } while (true);

1819}

1820

1821

1822

1823

1824

1825

1826

1827

1828bool ModuleMapParser::parseModuleId(ModuleId &Id) {

1829 Id.clear();

1830 do {

1832 Id.push_back(

1834 consumeToken();

1835 } else {

1836 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);

1837 return true;

1838 }

1839

1841 break;

1842

1843 consumeToken();

1844 } while (true);

1845

1846 return false;

1847}

1848

1849namespace {

1850

1851

1852 enum AttributeKind {

1853

1854 AT_unknown,

1855

1856

1857 AT_system,

1858

1859

1860 AT_extern_c,

1861

1862

1863 AT_exhaustive,

1864

1865

1866 AT_no_undeclared_includes

1867 };

1868

1869}

1870

1871

1872

1873

1874

1875void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc,

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

1880 diag::note_mmap_rename_top_level_private_module);

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

1883 };

1884

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

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

1888 continue;

1889

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

1892 continue;

1895 Canonical.append("_Private");

1896

1897

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

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

1901 diag::warn_mmap_mismatched_private_submodule)

1903

1905 if (FrameworkLoc.isValid())

1906 FixItInitBegin = FrameworkLoc;

1907 if (ExplicitLoc.isValid())

1908 FixItInitBegin = ExplicitLoc;

1909

1911 FixedPrivModDecl.append("framework ");

1912 FixedPrivModDecl.append("module ");

1913 FixedPrivModDecl.append(Canonical);

1914

1915 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,

1917 continue;

1918 }

1919

1920

1922 ActiveModule->Name != Canonical) {

1924 diag::warn_mmap_mismatched_private_module_name)

1925 << ActiveModule->Name;

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

1928 }

1929 }

1930}

1931

1932

1933

1934

1935

1936

1937

1938

1939

1940

1941

1942

1943

1944

1945

1946

1947

1948

1949

1950void ModuleMapParser::parseModuleDecl() {

1954 parseExternModuleDecl();

1955 return;

1956 }

1957

1958

1962 bool Framework = false;

1963

1964

1966 ExplicitLoc = consumeToken();

1968 }

1969

1970

1972 FrameworkLoc = consumeToken();

1973 Framework = true;

1974 }

1975

1976

1978 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);

1979 consumeToken();

1980 HadError = true;

1981 return;

1982 }

1983 CurrModuleDeclLoc = consumeToken();

1984

1985

1986

1988 return parseInferredModuleDecl(Framework, Explicit);

1989

1990

1992 if (parseModuleId(Id)) {

1993 HadError = true;

1994 return;

1995 }

1996

1997 if (ActiveModule) {

1998 if (Id.size() > 1) {

1999 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)

2001

2002 HadError = true;

2003 return;

2004 }

2005 } else if (Id.size() == 1 && Explicit) {

2006

2007 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);

2010 HadError = true;

2011 }

2012

2013 Module *PreviousActiveModule = ActiveModule;

2014 if (Id.size() > 1) {

2015

2016

2017 ActiveModule = nullptr;

2018 const Module *TopLevelModule = nullptr;

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

2021 if (I == 0)

2022 TopLevelModule = Next;

2023 ActiveModule = Next;

2024 continue;

2025 }

2026

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

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

2029 << (ActiveModule

2031 : "");

2032 HadError = true;

2033 }

2034

2035 if (TopLevelModule &&

2037 assert(ModuleMapFID !=

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

2040 "top-level module");

2043 }

2044 }

2045

2046 StringRef ModuleName = Id.back().first;

2048

2049

2050 Attributes Attrs;

2051 if (parseOptionalAttributes(Attrs))

2052 return;

2053

2054

2057 << ModuleName;

2058 HadError = true;

2059 return;

2060 }

2062

2063

2064 Module *ShadowingModule = nullptr;

2066

2067

2068

2069

2071

2072 bool Inferred = Existing->IsInferred;

2073

2074

2075

2076

2077

2078

2079

2080

2081

2082

2083

2084

2085

2086

2087

2088 bool PartOfFramework = Framework || Existing->isPartOfFramework();

2089

2090

2091 bool ParsedAsMainInput =

2096 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) {

2097 ActiveModule = PreviousActiveModule;

2098

2101 consumeToken();

2102 else {

2103 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);

2104 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);

2105 HadError = true;

2106 }

2107 return;

2108 }

2109

2111 ShadowingModule = Existing;

2112 } else {

2113

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

2115 << ModuleName;

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

2117

2118

2121 consumeToken();

2122

2123 HadError = true;

2124 return;

2125 }

2126 }

2127

2128

2129 if (ShadowingModule) {

2130 ActiveModule =

2132 } else {

2135 }

2136

2138 if (Attrs.IsSystem || IsSystem)

2139 ActiveModule->IsSystem = true;

2140 if (Attrs.IsExternC)

2142 if (Attrs.NoUndeclaredIncludes)

2144 ActiveModule->Directory = Directory;

2145

2146 StringRef MapFileName(

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

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

2151 }

2152

2153

2154

2155

2159 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,

2160 StartLoc) &&

2161 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,

2162 StartLoc) &&

2164 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);

2165

2166 bool Done = false;

2167 do {

2168 switch (Tok.Kind) {

2171 Done = true;

2172 break;

2173

2175 parseConfigMacros();

2176 break;

2177

2179 parseConflict();

2180 break;

2181

2186 parseModuleDecl();

2187 break;

2188

2190 parseExportDecl();

2191 break;

2192

2194 parseExportAsDecl();

2195 break;

2196

2198 parseUseDecl();

2199 break;

2200

2202 parseRequiresDecl();

2203 break;

2204

2207 break;

2208

2213 else

2214 parseUmbrellaDirDecl(UmbrellaLoc);

2215 break;

2216 }

2217

2220 break;

2221

2224 break;

2225

2228 break;

2229

2231 parseLinkDecl();

2232 break;

2233

2234 default:

2235 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);

2236 consumeToken();

2237 break;

2238 }

2239 } while (!Done);

2240

2242 consumeToken();

2243 else {

2244 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);

2245 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);

2246 HadError = true;

2247 }

2248

2249

2250

2254

2255

2256

2258 ActiveModule->Parent) {

2262 }

2263

2264

2265 ActiveModule = PreviousActiveModule;

2266}

2267

2268

2269

2270

2271

2272void ModuleMapParser::parseExternModuleDecl() {

2274 SourceLocation ExternLoc = consumeToken();

2275

2276

2278 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);

2279 consumeToken();

2280 HadError = true;

2281 return;

2282 }

2283 consumeToken();

2284

2285

2287 if (parseModuleId(Id)) {

2288 HadError = true;

2289 return;

2290 }

2291

2292

2294 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);

2295 HadError = true;

2296 return;

2297 }

2299 consumeToken();

2300

2301 StringRef FileNameRef = FileName;

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

2304 ModuleMapFileName += Directory.getName();

2305 llvm::sys::path::append(ModuleMapFileName, FileName);

2306 FileNameRef = ModuleMapFileName;

2307 }

2310 *File, IsSystem,

2312 ? Directory

2313 : File->getDir(),

2314 FileID(), nullptr, ExternLoc);

2315}

2316

2317

2318

2319

2320

2321

2322

2323

2324

2325

2326

2327

2328

2329

2330

2331

2333 bool &IsRequiresExcludedHack) {

2334 if (Feature == "excluded" &&

2337 IsRequiresExcludedHack = true;

2338 return false;

2339 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {

2340 return false;

2341 }

2342

2343 return true;

2344}

2345

2346

2347

2348

2349

2350

2351

2352

2353

2354

2355

2356

2357void ModuleMapParser::parseRequiresDecl() {

2359

2360

2361 consumeToken();

2362

2363

2364 do {

2365 bool RequiredState = true;

2367 RequiredState = false;

2368 consumeToken();

2369 }

2370

2372 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);

2373 HadError = true;

2374 return;

2375 }

2376

2377

2378 std::string Feature = std::string(Tok.getString());

2379 consumeToken();

2380

2381 bool IsRequiresExcludedHack = false;

2382 bool ShouldAddRequirement =

2384

2385 if (IsRequiresExcludedHack)

2386 UsesRequiresExcludedHack.insert(ActiveModule);

2387

2388 if (ShouldAddRequirement) {

2389

2390 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,

2391 *Map.Target);

2392 }

2393

2395 break;

2396

2397

2398 consumeToken();

2399 } while (true);

2400}

2401

2402

2403

2404

2405

2406

2407

2408

2409

2410

2411void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,

2413

2415

2418

2420 LeadingToken = Tok.Kind;

2421 consumeToken();

2422 }

2425 }

2426

2429

2430 if (UsesRequiresExcludedHack.count(ActiveModule)) {

2431

2432

2434 }

2435

2442 return;

2443 }

2444 consumeToken();

2445 }

2446

2447

2450 << "header";

2451 HadError = true;

2452 return;

2453 }

2459

2460

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

2465 HadError = true;

2466 return;

2467 }

2468

2469

2470

2473

2475 enum Attribute { Size, ModTime, Unknown };

2476 StringRef Str = Tok.getString();

2478 switch (llvm::StringSwitch(Str)

2479 .Case("size", Size)

2480 .Case("mtime", ModTime)

2483 if (Header.Size)

2484 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;

2487 diag::err_mmap_invalid_header_attribute_value) << Str;

2489 break;

2490 }

2492 consumeToken();

2493 break;

2494

2495 case ModTime:

2497 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;

2500 diag::err_mmap_invalid_header_attribute_value) << Str;

2502 break;

2503 }

2505 consumeToken();

2506 break;

2507

2509 Diags.Report(Loc, diag::err_mmap_expected_header_attribute);

2511 break;

2512 }

2513 }

2514

2516 consumeToken();

2517 else {

2518 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);

2519 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);

2520 HadError = true;

2521 }

2522 }

2523

2524 bool NeedsFramework = false;

2525

2526

2527

2528 if (!Map.LangOpts.BuiltinHeadersInSystemModules ||

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

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

2532

2533 if (NeedsFramework)

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

2537}

2538

2542}

2543

2544

2545

2546

2547

2548void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {

2549

2552 << "umbrella";

2553 HadError = true;

2554 return;

2555 }

2556

2557 std::string DirName = std::string(Tok.getString());

2558 std::string DirNameAsWritten = DirName;

2560

2561

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

2563 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)

2565 HadError = true;

2566 return;

2567 }

2568

2569

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

2573 } else {

2575 PathName = Directory.getName();

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

2578 }

2579

2580 if (!Dir) {

2581 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)

2582 << DirName;

2583 return;

2584 }

2585

2586 if (UsesRequiresExcludedHack.count(ActiveModule)) {

2587

2588

2589

2590

2591 std::error_code EC;

2593 llvm::vfs::FileSystem &FS =

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

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

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

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

2600 }

2601 }

2602

2603

2605

2606 for (auto &Header : Headers)

2608 return;

2609 }

2610

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

2612 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)

2613 << OwningModule->getFullModuleName();

2614 HadError = true;

2615 return;

2616 }

2617

2618

2620}

2621

2622

2623

2624

2625

2626

2627

2628

2629

2630

2631void ModuleMapParser::parseExportDecl() {

2634

2635

2637 bool Wildcard = false;

2638 do {

2639

2641 ParsedModuleId.push_back(

2643 consumeToken();

2644

2646 consumeToken();

2647 continue;

2648 }

2649

2650 break;

2651 }

2652

2654 Wildcard = true;

2655 consumeToken();

2656 break;

2657 }

2658

2660 HadError = true;

2661 return;

2662 } while (true);

2663

2665 ExportLoc, ParsedModuleId, Wildcard

2666 };

2668}

2669

2670

2671

2672

2673

2674void ModuleMapParser::parseExportAsDecl() {

2676 consumeToken();

2677

2680 HadError = true;

2681 return;

2682 }

2683

2684 if (ActiveModule->Parent) {

2685 Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);

2686 consumeToken();

2687 return;

2688 }

2689

2692 Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as)

2694 } else {

2695 Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as)

2698 }

2699 }

2700

2703

2704 consumeToken();

2705}

2706

2707

2708

2709

2710

2711void ModuleMapParser::parseUseDecl() {

2713 auto KWLoc = consumeToken();

2714

2716 parseModuleId(ParsedModuleId);

2717

2718 if (ActiveModule->Parent)

2719 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);

2720 else

2722}

2723

2724

2725

2726

2727

2728void ModuleMapParser::parseLinkDecl() {

2731

2732

2733 bool IsFramework = false;

2735 consumeToken();

2736 IsFramework = true;

2737 }

2738

2739

2741 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)

2743 HadError = true;

2744 return;

2745 }

2746

2747 std::string LibraryName = std::string(Tok.getString());

2748 consumeToken();

2750 IsFramework));

2751}

2752

2753

2754

2755

2756

2757

2758

2759

2760void ModuleMapParser::parseConfigMacros() {

2763

2764

2765 if (ActiveModule->Parent) {

2766 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);

2767 }

2768

2769

2770 Attributes Attrs;

2771 if (parseOptionalAttributes(Attrs))

2772 return;

2773

2774 if (Attrs.IsExhaustive && !ActiveModule->Parent) {

2776 }

2777

2778

2779

2781 return;

2782

2783

2784 if (!ActiveModule->Parent) {

2786 }

2787 consumeToken();

2788

2789 do {

2790

2792 break;

2793 consumeToken();

2794

2795

2796

2798 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);

2799 break;

2800 }

2801

2802

2803 if (!ActiveModule->Parent) {

2805 }

2806 consumeToken();

2807 } while (true);

2808}

2809

2810

2812 std::string result;

2813 {

2814 llvm::raw_string_ostream OS(result);

2815

2816 for (unsigned I = 0, N = Id.size(); I != N; ++I) {

2817 if (I)

2818 OS << ".";

2819 OS << Id[I].first;

2820 }

2821 }

2822

2823 return result;

2824}

2825

2826

2827

2828

2829

2830void ModuleMapParser::parseConflict() {

2834

2835

2836 if (parseModuleId(Conflict.Id))

2837 return;

2838

2839

2841 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)

2843 return;

2844 }

2845 consumeToken();

2846

2847

2849 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)

2851 return;

2852 }

2854 consumeToken();

2855

2856

2858}

2859

2860

2861

2862

2863

2864

2865

2866

2867

2868

2869void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {

2872 bool Failed = false;

2873

2874

2875 if (!ActiveModule && !Framework) {

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

2877 Failed = true;

2878 }

2879

2880 if (ActiveModule) {

2881

2882 if (!Failed && ActiveModule->IsAvailable &&

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

2885 Failed = true;

2886 }

2887

2888

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

2893 diag::note_mmap_prev_definition);

2894 Failed = true;

2895 }

2896

2897

2898 if (Framework) {

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

2900 Framework = false;

2901 }

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

2905 }

2906

2907

2908 if (Failed) {

2910 consumeToken();

2913 consumeToken();

2914 }

2915 HadError = true;

2916 return;

2917 }

2918

2919

2920 Attributes Attrs;

2921 if (parseOptionalAttributes(Attrs))

2922 return;

2923

2924 if (ActiveModule) {

2925

2929 } else {

2930

2931 Map.InferredDirectories[Directory].InferModules = true;

2932 Map.InferredDirectories[Directory].Attrs = Attrs;

2933 Map.InferredDirectories[Directory].ModuleMapFID = ModuleMapFID;

2934

2935 }

2936

2937

2939 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);

2940 HadError = true;

2941 return;

2942 }

2944

2945

2946 bool Done = false;

2947 do {

2948 switch (Tok.Kind) {

2951 Done = true;

2952 break;

2953

2955 if (ActiveModule) {

2956 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)

2957 << (ActiveModule != nullptr);

2958 consumeToken();

2959 break;

2960 }

2961

2962 consumeToken();

2963

2965 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);

2966 break;

2967 }

2968

2969 Map.InferredDirectories[Directory].ExcludedModules.push_back(

2971 consumeToken();

2972 break;

2973

2975 if (!ActiveModule) {

2976 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)

2977 << (ActiveModule != nullptr);

2978 consumeToken();

2979 break;

2980 }

2981

2982 consumeToken();

2985 else

2987 diag::err_mmap_expected_export_wildcard);

2988 consumeToken();

2989 break;

2990

2996 default:

2997 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)

2998 << (ActiveModule != nullptr);

2999 consumeToken();

3000 break;

3001 }

3002 } while (!Done);

3003

3005 consumeToken();

3006 else {

3007 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);

3008 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);

3009 HadError = true;

3010 }

3011}

3012

3013

3014

3015

3016

3017

3018

3019

3020

3021

3022

3023

3024

3025bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {

3026 bool HadError = false;

3027

3029

3031

3032

3034 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);

3037 consumeToken();

3038 HadError = true;

3039 }

3040

3041

3042 AttributeKind Attribute

3043 = llvm::StringSwitch(Tok.getString())

3044 .Case("exhaustive", AT_exhaustive)

3045 .Case("extern_c", AT_extern_c)

3046 .Case("no_undeclared_includes", AT_no_undeclared_includes)

3047 .Case("system", AT_system)

3048 .Default(AT_unknown);

3049 switch (Attribute) {

3050 case AT_unknown:

3051 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)

3053 break;

3054

3055 case AT_system:

3056 Attrs.IsSystem = true;

3057 break;

3058

3059 case AT_extern_c:

3060 Attrs.IsExternC = true;

3061 break;

3062

3063 case AT_exhaustive:

3064 Attrs.IsExhaustive = true;

3065 break;

3066

3067 case AT_no_undeclared_includes:

3068 Attrs.NoUndeclaredIncludes = true;

3069 break;

3070 }

3071 consumeToken();

3072

3073

3075 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);

3076 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);

3078 HadError = true;

3079 }

3080

3082 consumeToken();

3083 }

3084

3085 return HadError;

3086}

3087

3088

3089

3090

3091

3093 do {

3094 switch (Tok.Kind) {

3096 return HadError;

3097

3102 parseModuleDecl();

3103 break;

3104

3128 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);

3129 HadError = true;

3130 consumeToken();

3131 break;

3132 }

3133 } while (true);

3134}

3135

3138 unsigned *Offset,

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

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

3142 = ParsedModuleMap.find(File);

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

3144 return Known->second;

3145

3146

3147 if (ID.isInvalid()) {

3148 auto FileCharacter =

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

3151 }

3152

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

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

3155 if (!Buffer)

3156 return ParsedModuleMap[File] = true;

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

3158 "invalid buffer offset");

3159

3160

3162 Buffer->getBufferStart(),

3163 Buffer->getBufferStart() + (Offset ? *Offset : 0),

3164 Buffer->getBufferEnd());

3169

3170 if (Offset) {

3172 assert(Loc.first == ID && "stopped in a different file?");

3173 *Offset = Loc.second;

3174 }

3175

3176

3177 for (const auto &Cb : Callbacks)

3178 Cb->moduleMapFileRead(Start, File, IsSystem);

3179

3181}

Defines the Diagnostic-related interfaces.

Defines the clang::FileManager interface and associated types.

#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.

llvm::MachO::Target Target

static bool isBuiltinHeaderName(StringRef FileName)

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

static bool isBuiltInModuleName(StringRef ModuleName)

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

static Module * getTopLevelOrNull(Module *M)

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

static void inferFrameworkLink(Module *Mod)

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

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

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

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.

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

Whether to add the requirement Feature to the module M.

static std::string formatModuleId(const ModuleId &Id)

Format a module-id into a string.

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

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

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.

__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)

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

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

bool isIgnored(unsigned DiagID, SourceLocation Loc) const

Determine whether the diagnostic is known to be ignored.

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

StringRef getName() const

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

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.

LLVM_DEPRECATED("Functions returning DirectoryEntry are deprecated.", "getOptionalDirectoryRef()") llvm LLVM_DEPRECATED("Functions returning FileEntry are deprecated.", "getOptionalFileRef()") llvm llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)

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

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...

bool isCompilingModule() const

Are we compiling a module?

std::string CurrentModule

The name of the current module, of which the main source file is a part.

Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.

bool LexFromRawLexer(Token &Result)

LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...

SourceLocation getSourceLocation(const char *Loc, unsigned TokLen=1) const

getSourceLocation - Return a source location identifier for the specified offset in the current file.

static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)

getSpelling - This method is used to get the spelling of a token into a preallocated buffer,...

Required to construct a Module.

SourceLocation getLocation()

bool terminatedByDirective()

bool parseModuleMapFile()

Parse a module map file.

ModuleMapParser(Lexer &L, SourceManager &SourceMgr, const TargetInfo *Target, DiagnosticsEngine &Diags, ModuleMap &Map, FileID ModuleMapFID, DirectoryEntryRef Directory, bool IsSystem)

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

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

bool resolveExports(Module *Mod, bool Complain)

Resolve all of the unresolved exports in the given module.

void addLinkAsDependency(Module *Mod)

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

void dump()

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

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.

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

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

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

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

void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap)

OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const

static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)

Convert a header role to a kind.

Module * findModule(StringRef Name) const

Retrieve a module with the given name.

bool mayShadowNewModule(Module *ExistingModule)

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

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

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

Create a C++20 header unit.

static bool isModular(ModuleHeaderRole Role)

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

bool resolveConflicts(Module *Mod, bool Complain)

Resolve all of the unresolved conflicts in the given module.

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

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

void resolveHeaderDirectives(const FileEntry *File) const

Resolve all lazy header directives for the specified file.

module_iterator module_begin() const

ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const

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

OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const

bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, Module *Module) const

Module * createModuleForImplementationUnit(SourceLocation Loc, StringRef Name)

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

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

Construct a new module map.

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

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

FileID getModuleMapFileIDForUniquing(const Module *M) const

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

void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)

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

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

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.

bool isBuiltinHeader(FileEntryRef File)

Is this a compiler builtin header?

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

Create new submodule, assuming it does not exist.

module_iterator module_end() const

bool isHeaderInUnavailableModule(FileEntryRef Header) const

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

FileID getContainingModuleMapFileID(const Module *Module) const

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

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

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

~ModuleMap()

Destroy the module map.

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

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

void setTarget(const TargetInfo &Target)

Set the target information.

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

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

void resolveLinkAsDependencies(Module *Mod)

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

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.

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

Adds this header to the given module.

Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)

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

Module * findOrInferSubmodule(Module *Parent, StringRef Name)

ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)

Retrieve all the modules that contain the given header file.

Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent)

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...

static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)

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

bool resolveUses(Module *Mod, bool Complain)

Resolve all of the unresolved uses in the given module.

Describes a module or submodule.

StringRef getTopLevelModuleName() const

Retrieve the name of the top-level module.

void addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target)

Add the given feature requirement to the list of features required by this module.

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.

bool directlyUses(const Module *Requested)

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

std::vector< std::string > ConfigMacros

The set of "configuration macros", which are macros that (intentionally) change how this module is bu...

SourceLocation InferredSubmoduleLoc

The location of the inferred submodule.

unsigned IsUnimportable

Whether this module has declared itself unimportable, either because it's missing a requirement from ...

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.

unsigned IsExternC

Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...

unsigned ModuleMapIsPrivate

Whether this module came from a "private" module map, found next to a regular (public) module map.

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.

SmallVector< ModuleId, 2 > UnresolvedDirectUses

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

unsigned NoUndeclaredIncludes

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

unsigned ConfigMacrosExhaustive

Whether the set of configuration macros is exhaustive.

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.

unsigned IsFromModuleFile

Whether this module was loaded from a module file.

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 IsAvailable

Whether this module is available in the current translation unit.

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.

Parser - This implements a parser for the C family of languages.

Encodes a location in the source.

static SourceLocation getFromRawEncoding(UIntTy Encoding)

Turn a raw encoding of a SourceLocation object into a real SourceLocation.

bool isValid() const

Return true if this is a valid SourceLocation object.

UIntTy getRawEncoding() const

When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.

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

FileID getFileID(SourceLocation SpellingLoc) const

Return the FileID for a SourceLocation.

OptionalFileEntryRef getFileEntryRefForID(FileID FID) const

Returns the FileEntryRef for the provided FileID.

FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)

Create a new FileID that represents the specified file being #included from the specified IncludePosi...

FileManager & getFileManager() const

FileID getMainFileID() const

Returns the FileID of the main source file.

std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const

Decompose the specified location into a raw FileID + Offset pair.

const FileEntry * getFileEntryForID(FileID FID) const

Returns the FileEntry record for the provided FileID.

SourceLocation getLocForStartOfFile(FileID FID) const

Return the source location corresponding to the first byte of the specified file.

std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const

Return the buffer for the specified FileID.

A trivial tuple used to represent a source range.

StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...

StringLiteral - This represents a string literal expression, e.g.

Exposes information about the current target.

Token - This structure provides full information about a lexed token.

SourceLocation getLocation() const

Return a source location identifier for the specified offset in the current file.

unsigned getLength() const

bool is(tok::TokenKind K) const

is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....

tok::TokenKind getKind() const

bool isAtStartOfLine() const

isAtStartOfLine - Return true if this token is at the start of a line.

bool hasUDSuffix() const

Return true if this token is a string or character literal which has a ud-suffix.

StringRef getRawIdentifier() const

getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...

Defines the clang::TargetInfo interface.

bool Sub(InterpState &S, CodePtr OpPC)

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

if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))

LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)

@ 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.

@ 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].

A token in a module map file.

SourceLocation getLocation() const

bool is(TokenKind K) const

SourceLocation::UIntTy Location

StringRef getString() const

enum clang::MMToken::TokenKind Kind

uint64_t getInteger() const

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.

An unresolved conflict with another module.

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 ...