@@ -2749,12 +2749,95 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
2749
2749
didVerifyAttrs = true ;
2750
2750
}
2751
2751
2752
+ void writeDiscriminatorsIfNeeded (const ValueDecl *value) {
2753
+ using namespace decls_block ;
2754
+
2755
+ auto *storage = dyn_cast<AbstractStorageDecl>(value);
2756
+ auto access = value->getFormalAccess ();
2757
+ // Emit the private descriminator for private decls.
2758
+ // FIXME: We shouldn't need to encode this for /all/ private decls.
2759
+ // In theory we can follow the same rules as mangling and only include
2760
+ // the outermost private context.
2761
+ bool shouldEmitPrivateDescriminator =
2762
+ access <= swift::AccessLevel::FilePrivate &&
2763
+ !value->getDeclContext ()->isLocalContext ();
2764
+
2765
+ // Emit the the filename for private mapping for private decls and
2766
+ // decls with private accessors if compiled with -enable-private-imports.
2767
+ bool shouldEmitFilenameForPrivate =
2768
+ S.M ->arePrivateImportsEnabled () &&
2769
+ !value->getDeclContext ()->isLocalContext () &&
2770
+ (access <= swift::AccessLevel::FilePrivate ||
2771
+ (storage &&
2772
+ storage->getFormalAccess () >= swift::AccessLevel::Internal &&
2773
+ storage->hasPrivateAccessor ()));
2774
+
2775
+ if (shouldEmitFilenameForPrivate || shouldEmitPrivateDescriminator) {
2776
+ auto topLevelContext = value->getDeclContext ()->getModuleScopeContext ();
2777
+ if (auto *enclosingFile = dyn_cast<FileUnit>(topLevelContext)) {
2778
+ if (shouldEmitPrivateDescriminator) {
2779
+ Identifier discriminator =
2780
+ enclosingFile->getDiscriminatorForPrivateValue (value);
2781
+ unsigned abbrCode =
2782
+ S.DeclTypeAbbrCodes [PrivateDiscriminatorLayout::Code];
2783
+ PrivateDiscriminatorLayout::emitRecord (
2784
+ S.Out , S.ScratchRecord , abbrCode,
2785
+ S.addDeclBaseNameRef (discriminator));
2786
+ }
2787
+ auto getFilename = [](FileUnit *enclosingFile,
2788
+ const ValueDecl *decl) -> StringRef {
2789
+ if (auto *SF = dyn_cast<SourceFile>(enclosingFile)) {
2790
+ return llvm::sys::path::filename (SF->getFilename ());
2791
+ } else if (auto *LF = dyn_cast<LoadedFile>(enclosingFile)) {
2792
+ return LF->getFilenameForPrivateDecl (decl);
2793
+ }
2794
+ return StringRef ();
2795
+ };
2796
+ if (shouldEmitFilenameForPrivate) {
2797
+ auto filename = getFilename (enclosingFile, value);
2798
+ if (!filename.empty ()) {
2799
+ auto filenameID = S.addFilename (filename);
2800
+ FilenameForPrivateLayout::emitRecord (
2801
+ S.Out , S.ScratchRecord ,
2802
+ S.DeclTypeAbbrCodes [FilenameForPrivateLayout::Code],
2803
+ filenameID);
2804
+ }
2805
+ }
2806
+ }
2807
+ }
2808
+
2809
+ if (value->getDeclContext ()->isLocalContext ()) {
2810
+ auto discriminator = value->getLocalDiscriminator ();
2811
+ auto abbrCode = S.DeclTypeAbbrCodes [LocalDiscriminatorLayout::Code];
2812
+ LocalDiscriminatorLayout::emitRecord (S.Out , S.ScratchRecord , abbrCode,
2813
+ discriminator);
2814
+ }
2815
+ }
2816
+
2752
2817
public:
2753
2818
DeclSerializer (Serializer &S, DeclID id) : S(S), id(id) {}
2754
2819
~DeclSerializer () {
2755
2820
assert (didVerifyAttrs);
2756
2821
}
2757
2822
2823
+ void visit (const Decl *D) {
2824
+ // Emit attributes (if any).
2825
+ for (auto Attr : D->getAttrs ())
2826
+ S.writeDeclAttribute (Attr);
2827
+
2828
+ if (auto VD = dyn_cast<ValueDecl>(D)) {
2829
+ // Hack: synthesize a 'final' attribute if finality was inferred.
2830
+ if (VD->isFinal () && !D->getAttrs ().hasAttribute <FinalAttr>())
2831
+ S.writeDeclAttribute (
2832
+ new (D->getASTContext ()) FinalAttr (/* Implicit=*/ false ));
2833
+ }
2834
+
2835
+ if (auto *value = dyn_cast<ValueDecl>(D))
2836
+ writeDiscriminatorsIfNeeded (value);
2837
+
2838
+ DeclVisitor<DeclSerializer>::visit (const_cast <Decl *>(D));
2839
+ }
2840
+
2758
2841
void visitDecl (const Decl *) {
2759
2842
llvm_unreachable (" I guess we forgot a Decl kind?" );
2760
2843
}
@@ -3653,80 +3736,7 @@ void Serializer::writeDecl(const Decl *D) {
3653
3736
3654
3737
assert (!D->hasClangNode () && " imported decls should use cross-references" );
3655
3738
3656
- // Emit attributes (if any).
3657
- auto &Attrs = D->getAttrs ();
3658
- if (Attrs.begin () != Attrs.end ()) {
3659
- for (auto Attr : Attrs)
3660
- writeDeclAttribute (Attr);
3661
- }
3662
-
3663
- if (auto VD = dyn_cast<ValueDecl>(D)) {
3664
- if (VD->isFinal () && !D->getAttrs ().hasAttribute <FinalAttr>())
3665
- writeDeclAttribute (new (D->getASTContext ()) FinalAttr (/* Implicit=*/ false ));
3666
- }
3667
-
3668
- if (auto *value = dyn_cast<ValueDecl>(D)) {
3669
- auto *storage = dyn_cast<AbstractStorageDecl>(value);
3670
- auto access = value->getFormalAccess ();
3671
- // Emit the private descriminator for private decls.
3672
- // FIXME: We shouldn't need to encode this for /all/ private decls.
3673
- // In theory we can follow the same rules as mangling and only include
3674
- // the outermost private context.
3675
- bool shouldEmitPrivateDescriminator =
3676
- access <= swift::AccessLevel::FilePrivate &&
3677
- !value->getDeclContext ()->isLocalContext ();
3678
-
3679
- // Emit the the filename for private mapping for private decls and
3680
- // decls with private accessors if compiled with -enable-private-imports.
3681
- bool shouldEmitFilenameForPrivate =
3682
- M->arePrivateImportsEnabled () &&
3683
- !value->getDeclContext ()->isLocalContext () &&
3684
- (access <= swift::AccessLevel::FilePrivate ||
3685
- (storage &&
3686
- storage->getFormalAccess () >= swift::AccessLevel::Internal &&
3687
- storage->hasPrivateAccessor ()));
3688
-
3689
- if (shouldEmitFilenameForPrivate || shouldEmitPrivateDescriminator) {
3690
- auto topLevelContext = value->getDeclContext ()->getModuleScopeContext ();
3691
- if (auto *enclosingFile = dyn_cast<FileUnit>(topLevelContext)) {
3692
- if (shouldEmitPrivateDescriminator) {
3693
- Identifier discriminator =
3694
- enclosingFile->getDiscriminatorForPrivateValue (value);
3695
- unsigned abbrCode =
3696
- DeclTypeAbbrCodes[PrivateDiscriminatorLayout::Code];
3697
- PrivateDiscriminatorLayout::emitRecord (
3698
- Out, ScratchRecord, abbrCode, addDeclBaseNameRef (discriminator));
3699
- }
3700
- auto getFilename = [](FileUnit *enclosingFile,
3701
- const ValueDecl *decl) -> StringRef {
3702
- if (auto *SF = dyn_cast<SourceFile>(enclosingFile)) {
3703
- return llvm::sys::path::filename (SF->getFilename ());
3704
- } else if (auto *LF = dyn_cast<LoadedFile>(enclosingFile)) {
3705
- return LF->getFilenameForPrivateDecl (decl);
3706
- }
3707
- return StringRef ();
3708
- };
3709
- if (shouldEmitFilenameForPrivate) {
3710
- auto filename = getFilename (enclosingFile, value);
3711
- if (!filename.empty ()) {
3712
- auto filenameID = addFilename (filename);
3713
- FilenameForPrivateLayout::emitRecord (
3714
- Out, ScratchRecord,
3715
- DeclTypeAbbrCodes[FilenameForPrivateLayout::Code], filenameID);
3716
- }
3717
- }
3718
- }
3719
- }
3720
-
3721
- if (value->getDeclContext ()->isLocalContext ()) {
3722
- auto discriminator = value->getLocalDiscriminator ();
3723
- auto abbrCode = DeclTypeAbbrCodes[LocalDiscriminatorLayout::Code];
3724
- LocalDiscriminatorLayout::emitRecord (Out, ScratchRecord, abbrCode,
3725
- discriminator);
3726
- }
3727
- }
3728
-
3729
- DeclSerializer (*this , id).visit (const_cast <Decl *>(D));
3739
+ DeclSerializer (*this , id).visit (D);
3730
3740
}
3731
3741
3732
3742
#define SIMPLE_CASE (TYPENAME, VALUE ) \
0 commit comments