@@ -3801,6 +3801,131 @@ void MissingMemberFailure::diagnoseUnsafeCxxMethod(SourceLoc loc,
3801
3801
!isa_and_nonnull<clang::CXXRecordDecl>(
3802
3802
baseType->getAnyNominal ()->getClangDecl ()))
3803
3803
return ;
3804
+
3805
+ if (name.getBaseIdentifier ().str () == " getFromPointer" ||
3806
+ name.getBaseIdentifier ().str () == " isValid" ||
3807
+ name.getBaseIdentifier ().str () == " __dataUnsafe" ||
3808
+ name.getBaseIdentifier ().str () == " __getOpaquePointerValueUnsafe" ||
3809
+ name.getBaseIdentifier ().str () == " __getStartUnsafe" ||
3810
+ name.getBaseIdentifier ().str () == " __c_strUnsafe" ) {
3811
+ // OK, we did not find a member that we probably should have.
3812
+ // Dump the world.
3813
+ llvm::dbgs () << " ====================================================\n " ;
3814
+ llvm::dbgs () << " ====================================================\n\n " ;
3815
+ 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 " ;
3816
+ llvm::dbgs () << " ====================================================\n " ;
3817
+ llvm::dbgs () << " ====================================================\n\n " ;
3818
+
3819
+ llvm::dbgs () << " THE NAME: " ; name.dump ();
3820
+
3821
+ llvm::dbgs () << " ====================================================\n " ;
3822
+ llvm::dbgs () << " ====================================================\n\n " ;
3823
+
3824
+ auto cxxRecord = cast<clang::CXXRecordDecl>(baseType->getAnyNominal ()->getClangDecl ());
3825
+ llvm::dbgs () << " CXX RECORD: " ; cxxRecord->dump ();
3826
+
3827
+ llvm::dbgs () << " ====================================================\n " ;
3828
+ llvm::dbgs () << " ====================================================\n\n " ;
3829
+
3830
+ auto dumpRedecls = [](const clang::CXXRecordDecl *cxxRecordToDump) {
3831
+ llvm::dbgs () << " REDECLS:\n " ;
3832
+ unsigned redeclIdx = 0 ;
3833
+ for (auto redecl : cxxRecordToDump->redecls ()) {
3834
+ llvm::dbgs () << " REDECL(" << redeclIdx << " ): " ; redecl->dump ();
3835
+ redeclIdx++;
3836
+ }
3837
+ };
3838
+
3839
+ dumpRedecls (cxxRecord);
3840
+
3841
+ llvm::dbgs () << " ====================================================\n " ;
3842
+ llvm::dbgs () << " ====================================================\n\n " ;
3843
+ if (name.getBaseIdentifier ().str () == " getFromPointer" ||
3844
+ name.getBaseIdentifier ().str () == " isValid" ) {
3845
+ llvm::dbgs () << " LOOKUP UNSAFE VERSION:\n " ;
3846
+ auto unsafeId =
3847
+ ctx.getIdentifier (" __" + name.getBaseIdentifier ().str ().str () + " Unsafe" );
3848
+ for (auto found :
3849
+ baseType->getAnyNominal ()->lookupDirect (DeclBaseName (unsafeId))) {
3850
+ llvm::dbgs () << " **FOUND UNSAFE VERSION**\n " ;
3851
+ llvm::dbgs () << " UNSAFE: " ;
3852
+ found->dump ();
3853
+
3854
+ if (auto cxxMethod = dyn_cast_or_null<clang::CXXMethodDecl>(found->getClangDecl ())) {
3855
+ llvm::dbgs () << " FOUND CXX METHOD." ;
3856
+ auto returnType = cxxMethod->getReturnType ();
3857
+ llvm::dbgs () << " CXX METHOD RETURN TYPE: " ;
3858
+ returnType->dump ();
3859
+
3860
+ llvm::dbgs () << " CAN RETURN TYPE: " ;
3861
+ returnType->getCanonicalTypeUnqualified ().dump ();
3862
+
3863
+ if (auto recordType = dyn_cast<clang::RecordType>(returnType)) {
3864
+ dumpRedecls (returnType->getAsCXXRecordDecl ());
3865
+ } else {
3866
+ llvm::dbgs () << " NOT A RECORD TYPE\n " ;
3867
+ }
3868
+ }
3869
+ }
3870
+ } else {
3871
+ std::string safeName;
3872
+ if (name.getBaseIdentifier ().str () == " __dataUnsafe" )
3873
+ safeName = " data" ;
3874
+ if (name.getBaseIdentifier ().str () == " __getOpaquePointerValueUnsafe" )
3875
+ safeName = " getOpaquePointerValue" ;
3876
+ if (name.getBaseIdentifier ().str () == " __getStartUnsafe" )
3877
+ safeName = " getStart" ;
3878
+ if (name.getBaseIdentifier ().str () == " __c_strUnsafe" )
3879
+ safeName = " c_str" ;
3880
+
3881
+ auto safeId = ctx.getIdentifier (safeName);
3882
+ for (auto found :
3883
+ baseType->getAnyNominal ()->lookupDirect (DeclBaseName (safeId))) {
3884
+ llvm::dbgs () << " **FOUND SAFE VERSION**\n " ;
3885
+ llvm::dbgs () << " UNSAFE: " ;
3886
+ found->dump ();
3887
+
3888
+ if (auto cxxMethod = dyn_cast_or_null<clang::CXXMethodDecl>(found->getClangDecl ())) {
3889
+ llvm::dbgs () << " FOUND CXX METHOD." ;
3890
+ auto returnType = cxxMethod->getReturnType ();
3891
+ llvm::dbgs () << " CXX METHOD RETURN TYPE: " ;
3892
+ returnType->dump ();
3893
+
3894
+ llvm::dbgs () << " CAN RETURN TYPE: " ;
3895
+ returnType->getCanonicalTypeUnqualified ().dump ();
3896
+
3897
+ if (auto recordType = dyn_cast<clang::RecordType>(returnType)) {
3898
+ dumpRedecls (returnType->getAsCXXRecordDecl ());
3899
+ } else {
3900
+ llvm::dbgs () << " NOT A RECORD TYPE\n " ;
3901
+ }
3902
+ }
3903
+ }
3904
+ }
3905
+
3906
+ llvm::dbgs () << " ====================================================\n " ;
3907
+ llvm::dbgs () << " ====================================================\n\n " ;
3908
+ llvm::dbgs () << " (IMPORTED) SWIFT TYPE: " ;
3909
+ baseType->dump ();
3910
+
3911
+ llvm::dbgs () << " (IMPORTED) SWIFT DECL: " ;
3912
+ baseType->getAnyNominal ()->dump ();
3913
+
3914
+ // And for my final trick, I will dump the whole lookup table.
3915
+ llvm::dbgs () << " ====================================================\n " ;
3916
+ llvm::dbgs () << " ====================================================\n\n " ;
3917
+ llvm::dbgs () << " LOOKUP TABLE: " ;
3918
+
3919
+ if (auto clangModule = cxxRecord->getOwningModule ()) {
3920
+ dumpSwiftLookupTable (ctx.getClangModuleLoader ()->findLookupTable (clangModule));
3921
+ } else {
3922
+ llvm::dbgs () << " NO MODULE\n " ;
3923
+ }
3924
+
3925
+ llvm::dbgs () << " ====================================================\n " ;
3926
+ llvm::dbgs () << " DBUG DUMP DONE\n " ;
3927
+ llvm::dbgs () << " ====================================================\n\n " ;
3928
+ }
3804
3929
3805
3930
auto unsafeId =
3806
3931
ctx.getIdentifier (" __" + name.getBaseIdentifier ().str ().str () + " Unsafe" );
0 commit comments