@@ -780,6 +780,30 @@ void SourceFile::lookupObjCMethods(
780
780
results.append (known->second .begin (), known->second .end ());
781
781
}
782
782
783
+ bool ModuleDecl::shouldCollectDisplayDecls () const {
784
+ for (const FileUnit *file : Files) {
785
+ if (!file->shouldCollectDisplayDecls ())
786
+ return false ;
787
+ }
788
+ return true ;
789
+ }
790
+
791
+ static void collectParsedExportedImports (const ModuleDecl *M, SmallPtrSetImpl<ModuleDecl *> &Imports) {
792
+ for (const FileUnit *file : M->getFiles ()) {
793
+ if (const SourceFile *source = dyn_cast<SourceFile>(file)) {
794
+ if (source->hasImports ()) {
795
+ for (auto import : source->getImports ()) {
796
+ if (import .options .contains (ImportFlags::Exported) &&
797
+ !Imports.contains (import .module .importedModule ) &&
798
+ import .module .importedModule ->shouldCollectDisplayDecls ()) {
799
+ Imports.insert (import .module .importedModule );
800
+ }
801
+ }
802
+ }
803
+ }
804
+ }
805
+ }
806
+
783
807
void ModuleDecl::getLocalTypeDecls (SmallVectorImpl<TypeDecl*> &Results) const {
784
808
FORWARD (getLocalTypeDecls, (Results));
785
809
}
@@ -788,6 +812,24 @@ void ModuleDecl::getTopLevelDecls(SmallVectorImpl<Decl*> &Results) const {
788
812
FORWARD (getTopLevelDecls, (Results));
789
813
}
790
814
815
+ void ModuleDecl::dumpDisplayDecls () const {
816
+ SmallVector<Decl *, 32 > Decls;
817
+ getDisplayDecls (Decls);
818
+ for (auto *D : Decls) {
819
+ D->dump (llvm::errs ());
820
+ llvm::errs () << " \n " ;
821
+ }
822
+ }
823
+
824
+ void ModuleDecl::dumpTopLevelDecls () const {
825
+ SmallVector<Decl *, 32 > Decls;
826
+ getTopLevelDecls (Decls);
827
+ for (auto *D : Decls) {
828
+ D->dump (llvm::errs ());
829
+ llvm::errs () << " \n " ;
830
+ }
831
+ }
832
+
791
833
void ModuleDecl::getExportedPrespecializations (
792
834
SmallVectorImpl<Decl *> &Results) const {
793
835
FORWARD (getExportedPrespecializations, (Results));
@@ -907,9 +949,34 @@ SourceFile::getExternalRawLocsForDecl(const Decl *D) const {
907
949
return Result;
908
950
}
909
951
910
- void ModuleDecl::getDisplayDecls (SmallVectorImpl<Decl*> &Results) const {
952
+ void ModuleDecl::getDisplayDecls (SmallVectorImpl<Decl*> &Results, bool Recursive) const {
953
+ if (Recursive && isParsedModule (this )) {
954
+ SmallPtrSet<ModuleDecl *, 4 > Modules;
955
+ collectParsedExportedImports (this , Modules);
956
+ for (const ModuleDecl *import : Modules) {
957
+ import ->getDisplayDecls (Results, Recursive);
958
+ }
959
+ }
911
960
// FIXME: Should this do extra access control filtering?
912
961
FORWARD (getDisplayDecls, (Results));
962
+
963
+ #ifndef NDEBUG
964
+ if (Recursive) {
965
+ llvm::DenseSet<Decl *> visited;
966
+ for (auto *D : Results) {
967
+ // decls synthesized from implicit clang decls may appear multiple times;
968
+ // e.g. if multiple modules with underlying clang modules are re-exported.
969
+ // including duplicates of these is harmless, so skip them when counting
970
+ // this assertion
971
+ if (const auto *CD = D->getClangDecl ()) {
972
+ if (CD->isImplicit ()) continue ;
973
+ }
974
+
975
+ auto inserted = visited.insert (D).second ;
976
+ assert (inserted && " there should be no duplicate decls" );
977
+ }
978
+ }
979
+ #endif
913
980
}
914
981
915
982
ProtocolConformanceRef
@@ -3065,6 +3132,22 @@ void FileUnit::getTopLevelDeclsWhereAttributesMatch(
3065
3132
Results.erase (newEnd, Results.end ());
3066
3133
}
3067
3134
3135
+ void FileUnit::dumpDisplayDecls () const {
3136
+ SmallVector<Decl *, 32 > Decls;
3137
+ getDisplayDecls (Decls);
3138
+ for (auto *D : Decls) {
3139
+ D->dump (llvm::errs ());
3140
+ }
3141
+ }
3142
+
3143
+ void FileUnit::dumpTopLevelDecls () const {
3144
+ SmallVector<Decl *, 32 > Decls;
3145
+ getTopLevelDecls (Decls);
3146
+ for (auto *D : Decls) {
3147
+ D->dump (llvm::errs ());
3148
+ }
3149
+ }
3150
+
3068
3151
void swift::simple_display (llvm::raw_ostream &out, const FileUnit *file) {
3069
3152
if (!file) {
3070
3153
out << " (null)" ;
0 commit comments