@@ -54,7 +54,9 @@ class IncludeTree : public IncludeTreeBase<IncludeTree> {
54
54
class File ;
55
55
class FileList ;
56
56
class Node ;
57
+ class Module ;
57
58
class ModuleImport ;
59
+ class ModuleMap ;
58
60
59
61
Expected<File> getBaseFile ();
60
62
@@ -381,6 +383,262 @@ class IncludeTree::Node {
381
383
NodeKind K;
382
384
};
383
385
386
+ // / Module or submodule declaration as part of the \c IncludeTreeRoot module
387
+ // / map structure.
388
+ class IncludeTree ::Module : public IncludeTreeBase<Module> {
389
+ public:
390
+ static constexpr StringRef getNodeKind () { return " Modu" ; }
391
+
392
+ class ExportList ;
393
+ class LinkLibraryList ;
394
+
395
+ struct ModuleFlags {
396
+ bool IsFramework : 1 ;
397
+ bool IsExplicit : 1 ;
398
+ bool IsExternC : 1 ;
399
+ bool IsSystem : 1 ;
400
+ ModuleFlags ()
401
+ : IsFramework(false ), IsExplicit(false ), IsExternC(false ),
402
+ IsSystem (false ) {}
403
+ };
404
+
405
+ ModuleFlags getFlags () const ;
406
+
407
+ // / The name of the current (sub)module.
408
+ StringRef getName () const { return dataAfterFlags (); }
409
+
410
+ size_t getNumSubmodules () const ;
411
+
412
+ Expected<Module> getSubmodule (size_t I) {
413
+ assert (I < getNumSubmodules ());
414
+ auto Node = getCAS ().getProxy (getReference (I));
415
+ if (!Node)
416
+ return Node.takeError ();
417
+ return Module (*Node);
418
+ }
419
+
420
+ llvm::Error forEachSubmodule (llvm::function_ref<llvm::Error(Module)> CB);
421
+
422
+ std::optional<ObjectRef> getExportsRef () const {
423
+ if (std::optional<unsigned > Index = getExportsIndex ())
424
+ return getReference (*Index);
425
+ return std::nullopt;
426
+ }
427
+ std::optional<ObjectRef> getLinkLibrariesRef () const {
428
+ if (std::optional<unsigned > Index = getLinkLibrariesIndex ())
429
+ return getReference (*Index);
430
+ return std::nullopt;
431
+ }
432
+
433
+ // / The list of modules that this submodule re-exports.
434
+ Expected<std::optional<ExportList>> getExports ();
435
+
436
+ // / The list of modules that this submodule re-exports.
437
+ Expected<std::optional<LinkLibraryList>> getLinkLibraries ();
438
+
439
+ llvm::Error print (llvm::raw_ostream &OS, unsigned Indent = 0 );
440
+
441
+ static Expected<Module> create (ObjectStore &DB, StringRef ModuleName,
442
+ ModuleFlags Flags,
443
+ ArrayRef<ObjectRef> Submodules,
444
+ std::optional<ObjectRef> ExportList,
445
+ std::optional<ObjectRef> LinkLibraries);
446
+
447
+ static bool isValid (const ObjectProxy &Node) {
448
+ if (!IncludeTreeBase::isValid (Node))
449
+ return false ;
450
+ IncludeTreeBase Base (Node);
451
+ return Base.getData ().size () > 1 ;
452
+ }
453
+ static bool isValid (ObjectStore &DB, ObjectRef Ref) {
454
+ auto Node = DB.getProxy (Ref);
455
+ if (!Node) {
456
+ llvm::consumeError (Node.takeError ());
457
+ return false ;
458
+ }
459
+ return isValid (*Node);
460
+ }
461
+
462
+ private:
463
+ char rawFlags () const { return getData ()[0 ]; }
464
+ StringRef dataAfterFlags () const { return getData ().drop_front (); }
465
+ bool hasExports () const ;
466
+ bool hasLinkLibraries () const ;
467
+ std::optional<unsigned > getExportsIndex () const ;
468
+ std::optional<unsigned > getLinkLibrariesIndex () const ;
469
+
470
+ explicit Module (ObjectProxy Node) : IncludeTreeBase(std::move(Node)) {
471
+ assert (isValid (*this ));
472
+ }
473
+
474
+ friend class IncludeTreeBase <Module>;
475
+ friend class IncludeTreeRoot ;
476
+ friend class ModuleMap ;
477
+ };
478
+
479
+ // / The set of modules re-exported by another module.
480
+ class IncludeTree ::Module::ExportList : public IncludeTreeBase<ExportList> {
481
+ public:
482
+ static constexpr StringRef getNodeKind () { return " ExpL" ; }
483
+
484
+ // / An explicit export.
485
+ struct Export {
486
+ StringRef ModuleName;
487
+ bool Wildcard;
488
+ };
489
+
490
+ // / Whether this module exports all imported modules (`export *`).
491
+ bool hasGlobalWildcard () const ;
492
+
493
+ size_t getNumExplicitExports () const { return getNumReferences (); }
494
+
495
+ // / Whether the explicit export at \p I has a wildcard (`export MyModule.*`).
496
+ bool exportHasWildcard (size_t I) const ;
497
+
498
+ Expected<Export> getExplicitExport (size_t I);
499
+
500
+ // / Calls \p CB for each explicit export declaration.
501
+ llvm::Error forEachExplicitExport (llvm::function_ref<llvm::Error(Export)> CB);
502
+
503
+ llvm::Error print (llvm::raw_ostream &OS, unsigned Indent = 0 );
504
+
505
+ static Expected<ExportList> create (ObjectStore &DB, ArrayRef<Export> Exports,
506
+ bool GlobalWildcard);
507
+
508
+ static bool isValid (const ObjectProxy &Node) {
509
+ if (!IncludeTreeBase::isValid (Node))
510
+ return false ;
511
+ IncludeTreeBase Base (Node);
512
+ size_t ExpectedBitSize = Base.getNumReferences () + 1 ;
513
+ size_t ExpectedSize =
514
+ ExpectedBitSize / 8 + (ExpectedBitSize % 8 == 0 ? 0 : 1 );
515
+ return Base.getData ().size () == ExpectedSize;
516
+ }
517
+ static bool isValid (ObjectStore &DB, ObjectRef Ref) {
518
+ auto Node = DB.getProxy (Ref);
519
+ if (!Node) {
520
+ llvm::consumeError (Node.takeError ());
521
+ return false ;
522
+ }
523
+ return isValid (*Node);
524
+ }
525
+
526
+ private:
527
+ explicit ExportList (ObjectProxy Node) : IncludeTreeBase(std::move(Node)) {
528
+ assert (isValid (*this ));
529
+ }
530
+
531
+ friend class IncludeTreeBase <ExportList>;
532
+ friend class Module ;
533
+ };
534
+
535
+ // / The set of libraries to link against when using a module.
536
+ class IncludeTree ::Module::LinkLibraryList
537
+ : public IncludeTreeBase<LinkLibraryList> {
538
+ public:
539
+ static constexpr StringRef getNodeKind () { return " LnkL" ; }
540
+
541
+ struct LinkLibrary {
542
+ StringRef Library;
543
+ bool IsFramework;
544
+ };
545
+
546
+ size_t getNumLibraries () const { return getNumReferences (); }
547
+
548
+ // / Whether the library at \p I is a framework.
549
+ bool isFramework (size_t I) const ;
550
+
551
+ ObjectRef getLibraryNameRef (size_t I) const { return getReference (I); }
552
+
553
+ Expected<LinkLibrary> getLinkLibrary (size_t I) {
554
+ auto Name = getCAS ().getProxy (getLibraryNameRef (I));
555
+ if (!Name)
556
+ return Name.takeError ();
557
+ return LinkLibrary{Name->getData (), isFramework (I)};
558
+ }
559
+
560
+ // / Calls \p CB for each link libary.
561
+ llvm::Error
562
+ forEachLinkLibrary (llvm::function_ref<llvm::Error(LinkLibrary)> CB);
563
+
564
+ llvm::Error print (llvm::raw_ostream &OS, unsigned Indent = 0 );
565
+
566
+ static Expected<LinkLibraryList> create (ObjectStore &DB,
567
+ ArrayRef<LinkLibrary> Exports);
568
+
569
+ static bool isValid (const ObjectProxy &Node) {
570
+ if (!IncludeTreeBase::isValid (Node))
571
+ return false ;
572
+ IncludeTreeBase Base (Node);
573
+ size_t ExpectedBitSize = Base.getNumReferences ();
574
+ size_t ExpectedSize =
575
+ ExpectedBitSize / 8 + (ExpectedBitSize % 8 == 0 ? 0 : 1 );
576
+ return Base.getData ().size () == ExpectedSize;
577
+ }
578
+ static bool isValid (ObjectStore &DB, ObjectRef Ref) {
579
+ auto Node = DB.getProxy (Ref);
580
+ if (!Node) {
581
+ llvm::consumeError (Node.takeError ());
582
+ return false ;
583
+ }
584
+ return isValid (*Node);
585
+ }
586
+
587
+ private:
588
+ explicit LinkLibraryList (ObjectProxy Node)
589
+ : IncludeTreeBase(std::move(Node)) {
590
+ assert (isValid (*this ));
591
+ }
592
+
593
+ friend class IncludeTreeBase <LinkLibraryList>;
594
+ friend class Module ;
595
+ };
596
+
597
+ class IncludeTree ::ModuleMap : public IncludeTreeBase<ModuleMap> {
598
+ public:
599
+ static constexpr StringRef getNodeKind () { return " ModM" ; }
600
+
601
+ size_t getNumModules () const { return getNumReferences (); }
602
+
603
+ Expected<Module> getModule (size_t I) {
604
+ auto Node = getCAS ().getProxy (getReference (I));
605
+ if (!Node)
606
+ return Node.takeError ();
607
+ return Module (*Node);
608
+ }
609
+
610
+ // / Calls \p CB for each module declaration.
611
+ llvm::Error forEachModule (llvm::function_ref<llvm::Error(Module)> CB);
612
+
613
+ llvm::Error print (llvm::raw_ostream &OS, unsigned Indent = 0 );
614
+
615
+ static Expected<ModuleMap> create (ObjectStore &DB,
616
+ ArrayRef<ObjectRef> Modules);
617
+
618
+ static bool isValid (const ObjectProxy &Node) {
619
+ if (!IncludeTreeBase::isValid (Node))
620
+ return false ;
621
+ IncludeTreeBase Base (Node);
622
+ return Base.getData ().empty ();
623
+ }
624
+ static bool isValid (ObjectStore &DB, ObjectRef Ref) {
625
+ auto Node = DB.getProxy (Ref);
626
+ if (!Node) {
627
+ llvm::consumeError (Node.takeError ());
628
+ return false ;
629
+ }
630
+ return isValid (*Node);
631
+ }
632
+
633
+ private:
634
+ explicit ModuleMap (ObjectProxy Node) : IncludeTreeBase(std::move(Node)) {
635
+ assert (isValid (*this ));
636
+ }
637
+
638
+ friend class IncludeTreeBase <ModuleMap>;
639
+ friend class IncludeTreeRoot ;
640
+ };
641
+
384
642
// / Represents the include-tree result for a translation unit.
385
643
class IncludeTreeRoot : public IncludeTreeBase <IncludeTreeRoot> {
386
644
public:
@@ -426,12 +684,12 @@ class IncludeTreeRoot : public IncludeTreeBase<IncludeTreeRoot> {
426
684
return std::nullopt;
427
685
}
428
686
429
- Expected<std::optional<IncludeTree::File >> getModuleMapFile () {
687
+ Expected<std::optional<IncludeTree::ModuleMap >> getModuleMap () {
430
688
if (std::optional<ObjectRef> Ref = getModuleMapRef ()) {
431
689
auto Node = getCAS ().getProxy (*Ref);
432
690
if (!Node)
433
691
return Node.takeError ();
434
- return IncludeTree::File (*Node);
692
+ return IncludeTree::ModuleMap (*Node);
435
693
}
436
694
return std::nullopt;
437
695
}
0 commit comments