@@ -3817,6 +3817,131 @@ void MissingMemberFailure::diagnoseUnsafeCxxMethod(SourceLoc loc,
3817
3817
!isa_and_nonnull<clang::CXXRecordDecl>(
3818
3818
baseType->getAnyNominal ()->getClangDecl ()))
3819
3819
return ;
3820
+
3821
+ if (name.getBaseIdentifier ().str () == " getFromPointer" ||
3822
+ name.getBaseIdentifier ().str () == " isValid" ||
3823
+ name.getBaseIdentifier ().str () == " __dataUnsafe" ||
3824
+ name.getBaseIdentifier ().str () == " __getOpaquePointerValueUnsafe" ||
3825
+ name.getBaseIdentifier ().str () == " __getStartUnsafe" ||
3826
+ name.getBaseIdentifier ().str () == " __c_strUnsafe" ) {
3827
+ // OK, we did not find a member that we probably should have.
3828
+ // Dump the world.
3829
+ llvm::dbgs () << " ====================================================\n " ;
3830
+ llvm::dbgs () << " ====================================================\n\n " ;
3831
+ llvm::dbgs () << " Hello! You have unfortuantly stubled across an interop bug that we have been trying to track down for a while. Please reach out to Zoe Carver and provide a link to this build. You can re-run this build and it should work next time. Sorry for the inconvience.\n\n " ;
3832
+ llvm::dbgs () << " ====================================================\n " ;
3833
+ llvm::dbgs () << " ====================================================\n\n " ;
3834
+
3835
+ llvm::dbgs () << " THE NAME: " ; name.dump ();
3836
+
3837
+ llvm::dbgs () << " ====================================================\n " ;
3838
+ llvm::dbgs () << " ====================================================\n\n " ;
3839
+
3840
+ auto cxxRecord = cast<clang::CXXRecordDecl>(baseType->getAnyNominal ()->getClangDecl ());
3841
+ llvm::dbgs () << " CXX RECORD: " ; cxxRecord->dump ();
3842
+
3843
+ llvm::dbgs () << " ====================================================\n " ;
3844
+ llvm::dbgs () << " ====================================================\n\n " ;
3845
+
3846
+ auto dumpRedecls = [](const clang::CXXRecordDecl *cxxRecordToDump) {
3847
+ llvm::dbgs () << " REDECLS:\n " ;
3848
+ unsigned redeclIdx = 0 ;
3849
+ for (auto redecl : cxxRecordToDump->redecls ()) {
3850
+ llvm::dbgs () << " REDECL(" << redeclIdx << " ): " ; redecl->dump ();
3851
+ redeclIdx++;
3852
+ }
3853
+ };
3854
+
3855
+ dumpRedecls (cxxRecord);
3856
+
3857
+ llvm::dbgs () << " ====================================================\n " ;
3858
+ llvm::dbgs () << " ====================================================\n\n " ;
3859
+ if (name.getBaseIdentifier ().str () == " getFromPointer" ||
3860
+ name.getBaseIdentifier ().str () == " isValid" ) {
3861
+ llvm::dbgs () << " LOOKUP UNSAFE VERSION:\n " ;
3862
+ auto unsafeId =
3863
+ ctx.getIdentifier (" __" + name.getBaseIdentifier ().str ().str () + " Unsafe" );
3864
+ for (auto found :
3865
+ baseType->getAnyNominal ()->lookupDirect (DeclBaseName (unsafeId))) {
3866
+ llvm::dbgs () << " **FOUND UNSAFE VERSION**\n " ;
3867
+ llvm::dbgs () << " UNSAFE: " ;
3868
+ found->dump ();
3869
+
3870
+ if (auto cxxMethod = dyn_cast_or_null<clang::CXXMethodDecl>(found->getClangDecl ())) {
3871
+ llvm::dbgs () << " FOUND CXX METHOD." ;
3872
+ auto returnType = cxxMethod->getReturnType ();
3873
+ llvm::dbgs () << " CXX METHOD RETURN TYPE: " ;
3874
+ returnType->dump ();
3875
+
3876
+ llvm::dbgs () << " CAN RETURN TYPE: " ;
3877
+ returnType->getCanonicalTypeUnqualified ().dump ();
3878
+
3879
+ if (auto recordType = dyn_cast<clang::RecordType>(returnType)) {
3880
+ dumpRedecls (returnType->getAsCXXRecordDecl ());
3881
+ } else {
3882
+ llvm::dbgs () << " NOT A RECORD TYPE\n " ;
3883
+ }
3884
+ }
3885
+ }
3886
+ } else {
3887
+ std::string safeName;
3888
+ if (name.getBaseIdentifier ().str () == " __dataUnsafe" )
3889
+ safeName = " data" ;
3890
+ if (name.getBaseIdentifier ().str () == " __getOpaquePointerValueUnsafe" )
3891
+ safeName = " getOpaquePointerValue" ;
3892
+ if (name.getBaseIdentifier ().str () == " __getStartUnsafe" )
3893
+ safeName = " getStart" ;
3894
+ if (name.getBaseIdentifier ().str () == " __c_strUnsafe" )
3895
+ safeName = " c_str" ;
3896
+
3897
+ auto safeId = ctx.getIdentifier (safeName);
3898
+ for (auto found :
3899
+ baseType->getAnyNominal ()->lookupDirect (DeclBaseName (safeId))) {
3900
+ llvm::dbgs () << " **FOUND SAFE VERSION**\n " ;
3901
+ llvm::dbgs () << " UNSAFE: " ;
3902
+ found->dump ();
3903
+
3904
+ if (auto cxxMethod = dyn_cast_or_null<clang::CXXMethodDecl>(found->getClangDecl ())) {
3905
+ llvm::dbgs () << " FOUND CXX METHOD." ;
3906
+ auto returnType = cxxMethod->getReturnType ();
3907
+ llvm::dbgs () << " CXX METHOD RETURN TYPE: " ;
3908
+ returnType->dump ();
3909
+
3910
+ llvm::dbgs () << " CAN RETURN TYPE: " ;
3911
+ returnType->getCanonicalTypeUnqualified ().dump ();
3912
+
3913
+ if (auto recordType = dyn_cast<clang::RecordType>(returnType)) {
3914
+ dumpRedecls (returnType->getAsCXXRecordDecl ());
3915
+ } else {
3916
+ llvm::dbgs () << " NOT A RECORD TYPE\n " ;
3917
+ }
3918
+ }
3919
+ }
3920
+ }
3921
+
3922
+ llvm::dbgs () << " ====================================================\n " ;
3923
+ llvm::dbgs () << " ====================================================\n\n " ;
3924
+ llvm::dbgs () << " (IMPORTED) SWIFT TYPE: " ;
3925
+ baseType->dump ();
3926
+
3927
+ llvm::dbgs () << " (IMPORTED) SWIFT DECL: " ;
3928
+ baseType->getAnyNominal ()->dump ();
3929
+
3930
+ // And for my final trick, I will dump the whole lookup table.
3931
+ llvm::dbgs () << " ====================================================\n " ;
3932
+ llvm::dbgs () << " ====================================================\n\n " ;
3933
+ llvm::dbgs () << " LOOKUP TABLE: " ;
3934
+
3935
+ if (auto clangModule = cxxRecord->getOwningModule ()) {
3936
+ dumpSwiftLookupTable (ctx.getClangModuleLoader ()->findLookupTable (clangModule));
3937
+ } else {
3938
+ llvm::dbgs () << " NO MODULE\n " ;
3939
+ }
3940
+
3941
+ llvm::dbgs () << " ====================================================\n " ;
3942
+ llvm::dbgs () << " DBUG DUMP DONE\n " ;
3943
+ llvm::dbgs () << " ====================================================\n\n " ;
3944
+ }
3820
3945
3821
3946
auto unsafeId =
3822
3947
ctx.getIdentifier (" __" + name.getBaseIdentifier ().str ().str () + " Unsafe" );
0 commit comments