@@ -518,11 +518,12 @@ diagnoseUnqualifiedInit(UnresolvedDeclRefExpr *initExpr, DeclContext *dc,
518518                        initExpr->getNameLoc (), /* implicit=*/ true );
519519}
520520
521- // / Bind an UnresolvedDeclRefExpr by performing name lookup and
522- // / returning the resultant expression. Context is the DeclContext used
523- // / for the lookup.
524- Expr *TypeChecker::resolveDeclRefExpr (UnresolvedDeclRefExpr *UDRE,
525-                                       DeclContext *DC) {
521+ // / Bind an UnresolvedDeclRefExpr by performing name lookup using the given
522+ // / options and returning the resultant expression. `DC` is the DeclContext
523+ // / used for the lookup. If the lookup doesn't find any results, returns
524+ // / `nullptr`.
525+ static  Expr *resolveDeclRefExpr (UnresolvedDeclRefExpr *UDRE, DeclContext *DC,
526+                                 NameLookupOptions lookupOptions) {
526527  auto  &Context = DC->getASTContext ();
527528  DeclNameRef Name = UDRE->getName ();
528529  SourceLoc Loc = UDRE->getLoc ();
@@ -562,14 +563,6 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
562563    LookupName = DeclNameRef (lookupName);
563564  }
564565
565-   //  Perform standard value name lookup.
566-   NameLookupOptions lookupOptions = defaultUnqualifiedLookupOptions;
567-   //  TODO: Include all of the possible members to give a solver a
568-   //        chance to diagnose name shadowing which requires explicit
569-   //        name/module qualifier to access top-level name.
570-   lookupOptions |= NameLookupFlags::IncludeOuterResults;
571-   lookupOptions |= NameLookupFlags::IgnoreMissingImports;
572- 
573566  LookupResult Lookup;
574567
575568  bool  AllDeclRefs = true ;
@@ -628,17 +621,8 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
628621  }
629622
630623  if  (!Lookup) {
631-     //  If we failed lookup of an operator, check to see if this is a range
632-     //  operator misspelling. Otherwise try to diagnose a juxtaposition
633-     //  e.g. (x*-4) that needs whitespace.
634-     if  (diagnoseRangeOperatorMisspell (Context.Diags , UDRE) ||
635-         diagnoseIncDecOperator (Context.Diags , UDRE) ||
636-         diagnoseOperatorJuxtaposition (UDRE, DC) ||
637-         diagnoseNonexistentPowerOperator (Context.Diags , UDRE, DC)) {
638-       return  errorResult ();
639-     }
640- 
641-     //  Try ignoring access control.
624+     //  For the purpose of diagnosing inaccessible results, try the lookup again
625+     //  but ignore access control.
642626    NameLookupOptions relookupOptions = lookupOptions;
643627    relookupOptions |= NameLookupFlags::IgnoreAccessControl;
644628    auto  inaccessibleResults =
@@ -663,117 +647,8 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
663647      return  errorResult ();
664648    }
665649
666-     //  TODO: Name will be a compound name if it was written explicitly as
667-     //  one, but we should also try to propagate labels into this.
668-     DeclNameLoc nameLoc = UDRE->getNameLoc ();
669- 
670-     Identifier simpleName = Name.getBaseIdentifier ();
671-     const  char  *buffer = simpleName.get ();
672-     llvm::SmallString<64 > expectedIdentifier;
673-     bool  isConfused = false ;
674-     uint32_t  codepoint;
675-     uint32_t  firstConfusableCodepoint = 0 ;
676-     int  totalCodepoints = 0 ;
677-     int  offset = 0 ;
678-     while  ((codepoint = validateUTF8CharacterAndAdvance (buffer,
679-                                                         buffer +
680-                                                         strlen (buffer)))
681-            != ~0U ) {
682-       int  length = (buffer - simpleName.get ()) - offset;
683-       if  (auto  expectedCodepoint =
684-           confusable::tryConvertConfusableCharacterToASCII (codepoint)) {
685-         if  (firstConfusableCodepoint == 0 ) {
686-           firstConfusableCodepoint = codepoint;
687-         }
688-         isConfused = true ;
689-         expectedIdentifier += expectedCodepoint;
690-       } else  {
691-         expectedIdentifier += (char )codepoint;
692-       }
693- 
694-       totalCodepoints++;
695- 
696-       offset += length;
697-     }
698- 
699-     auto  emitBasicError = [&] {
700-       
701-       if  (Name.isSimpleName (Context.Id_self )) {
702-         //  `self` gets diagnosed with a different error when it can't be found.
703-         Context.Diags 
704-             .diagnose (Loc, diag::cannot_find_self_in_scope)
705-             .highlight (UDRE->getSourceRange ());
706-       } else  {
707-         Context.Diags 
708-             .diagnose (Loc, diag::cannot_find_in_scope, Name,
709-                       Name.isOperator ())
710-             .highlight (UDRE->getSourceRange ());
711-       }
712- 
713-       if  (!Context.LangOpts .DisableExperimentalClangImporterDiagnostics ) {
714-         Context.getClangModuleLoader ()->diagnoseTopLevelValue (
715-             Name.getFullName ());
716-       }
717-     };
718- 
719-     if  (!isConfused) {
720-       if  (Name.isSimpleName (Context.Id_Self )) {
721-         if  (DeclContext *typeContext = DC->getInnermostTypeContext ()){
722-           Type SelfType = typeContext->getSelfInterfaceType ();
723- 
724-           if  (typeContext->getSelfClassDecl () &&
725-               !typeContext->getSelfClassDecl ()->isForeignReferenceType ())
726-             SelfType = DynamicSelfType::get (SelfType, Context);
727-           return  new  (Context)
728-               TypeExpr (new  (Context) SelfTypeRepr (SelfType, Loc));
729-         }
730-       }
731- 
732-       TypoCorrectionResults corrections (Name, nameLoc);
733- 
734-       //  FIXME: Don't perform typo correction inside macro arguments, because it
735-       //  will invoke synthesizing declarations in this scope, which will attempt to
736-       //  expand this macro which leads to circular reference errors.
737-       if  (!namelookup::isInMacroArgument (DC->getParentSourceFile (), UDRE->getLoc ())) {
738-         TypeChecker::performTypoCorrection (DC, UDRE->getRefKind (), Type (),
739-                                            lookupOptions, corrections);
740-       }
741- 
742-       if  (auto  typo = corrections.claimUniqueCorrection ()) {
743-         auto  diag = Context.Diags .diagnose (
744-             Loc, diag::cannot_find_in_scope_corrected, Name,
745-             Name.isOperator (), typo->CorrectedName .getBaseIdentifier ().str ());
746-         diag.highlight (UDRE->getSourceRange ());
747-         typo->addFixits (diag);
748-       } else  {
749-         emitBasicError ();
750-       }
751- 
752-       corrections.noteAllCandidates ();
753-     } else  {
754-       emitBasicError ();
755- 
756-       if  (totalCodepoints == 1 ) {
757-         auto  charNames = confusable::getConfusableAndBaseCodepointNames (
758-             firstConfusableCodepoint);
759-         Context.Diags 
760-             .diagnose (Loc, diag::single_confusable_character,
761-                       UDRE->getName ().isOperator (), simpleName.str (),
762-                       charNames.first , expectedIdentifier, charNames.second )
763-             .fixItReplace (Loc, expectedIdentifier);
764-       } else  {
765-         Context.Diags 
766-             .diagnose (Loc, diag::confusable_character,
767-                       UDRE->getName ().isOperator (), simpleName.str (),
768-                       expectedIdentifier)
769-             .fixItReplace (Loc, expectedIdentifier);
770-       }
771-     }
772- 
773-     //  TODO: consider recovering from here.  We may want some way to suppress
774-     //  downstream diagnostics, though.
775- 
776-     return  errorResult ();
650+     //  No results were found.
651+     return  nullptr ;
777652  }
778653
779654  //  FIXME: Need to refactor the way we build an AST node from a lookup result!
@@ -892,8 +767,9 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
892767                                          UDRE->getNameLoc ().getStartLoc ());
893768    }
894769
895-     return  buildRefExpr (ResultValues, DC, UDRE->getNameLoc (),
896-                         UDRE->isImplicit (), UDRE->getFunctionRefInfo ());
770+     return  TypeChecker::buildRefExpr (ResultValues, DC, UDRE->getNameLoc (),
771+                                      UDRE->isImplicit (),
772+                                      UDRE->getFunctionRefInfo ());
897773  }
898774
899775  ResultValues.clear ();
@@ -983,6 +859,157 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
983859  return  errorResult ();
984860}
985861
862+ Expr *TypeChecker::resolveDeclRefExpr (UnresolvedDeclRefExpr *UDRE,
863+                                       DeclContext *DC) {
864+   auto  &Context = DC->getASTContext ();
865+ 
866+   //  Perform standard value name lookup.
867+   NameLookupOptions lookupOptions = defaultUnqualifiedLookupOptions;
868+   //  TODO: Include all of the possible members to give a solver a
869+   //        chance to diagnose name shadowing which requires explicit
870+   //        name/module qualifier to access top-level name.
871+   lookupOptions |= NameLookupFlags::IncludeOuterResults;
872+ 
873+   Expr *result = ::resolveDeclRefExpr (UDRE, DC, lookupOptions);
874+   if  (!result && Context.LangOpts .hasFeature (Feature::MemberImportVisibility,
875+                                              /* allowMigration=*/ true )) {
876+     //  If we didn't find a result, try again but this time relax
877+     //  MemberImportVisibility restrictions. Note that diagnosing the missing
878+     //  import is already handled by resolveDeclRefExpr().
879+     lookupOptions |= NameLookupFlags::IgnoreMissingImports;
880+     result = ::resolveDeclRefExpr (UDRE, DC, lookupOptions);
881+   }
882+ 
883+   if  (result)
884+     return  result;
885+ 
886+   //  We didn't find any results. Look for common mistakes to diagnose.
887+   DeclNameRef Name = UDRE->getName ();
888+   SourceLoc Loc = UDRE->getLoc ();
889+   if  (Loc.isInvalid ())
890+     DC = DC->getModuleScopeContext ();
891+ 
892+   auto  errorResult = [&]() -> Expr * {
893+     return  new  (Context) ErrorExpr (UDRE->getSourceRange ());
894+   };
895+ 
896+   //  If we failed lookup of an operator, check to see if this is a range
897+   //  operator misspelling. Otherwise try to diagnose a juxtaposition
898+   //  e.g. (x*-4) that needs whitespace.
899+   if  (diagnoseRangeOperatorMisspell (Context.Diags , UDRE) ||
900+       diagnoseIncDecOperator (Context.Diags , UDRE) ||
901+       diagnoseOperatorJuxtaposition (UDRE, DC) ||
902+       diagnoseNonexistentPowerOperator (Context.Diags , UDRE, DC)) {
903+     return  errorResult ();
904+   }
905+ 
906+   //  TODO: Name will be a compound name if it was written explicitly as
907+   //  one, but we should also try to propagate labels into this.
908+   DeclNameLoc nameLoc = UDRE->getNameLoc ();
909+ 
910+   Identifier simpleName = Name.getBaseIdentifier ();
911+   const  char  *buffer = simpleName.get ();
912+   llvm::SmallString<64 > expectedIdentifier;
913+   bool  isConfused = false ;
914+   uint32_t  codepoint;
915+   uint32_t  firstConfusableCodepoint = 0 ;
916+   int  totalCodepoints = 0 ;
917+   int  offset = 0 ;
918+   while  ((codepoint = validateUTF8CharacterAndAdvance (
919+               buffer, buffer + strlen (buffer))) != ~0U ) {
920+     int  length = (buffer - simpleName.get ()) - offset;
921+     if  (auto  expectedCodepoint =
922+             confusable::tryConvertConfusableCharacterToASCII (codepoint)) {
923+       if  (firstConfusableCodepoint == 0 ) {
924+         firstConfusableCodepoint = codepoint;
925+       }
926+       isConfused = true ;
927+       expectedIdentifier += expectedCodepoint;
928+     } else  {
929+       expectedIdentifier += (char )codepoint;
930+     }
931+ 
932+     totalCodepoints++;
933+ 
934+     offset += length;
935+   }
936+ 
937+   auto  emitBasicError = [&] {
938+     if  (Name.isSimpleName (Context.Id_self )) {
939+       //  `self` gets diagnosed with a different error when it can't be found.
940+       Context.Diags .diagnose (Loc, diag::cannot_find_self_in_scope)
941+           .highlight (UDRE->getSourceRange ());
942+     } else  {
943+       Context.Diags 
944+           .diagnose (Loc, diag::cannot_find_in_scope, Name, Name.isOperator ())
945+           .highlight (UDRE->getSourceRange ());
946+     }
947+ 
948+     if  (!Context.LangOpts .DisableExperimentalClangImporterDiagnostics ) {
949+       Context.getClangModuleLoader ()->diagnoseTopLevelValue (Name.getFullName ());
950+     }
951+   };
952+ 
953+   if  (!isConfused) {
954+     if  (Name.isSimpleName (Context.Id_Self )) {
955+       if  (DeclContext *typeContext = DC->getInnermostTypeContext ()) {
956+         Type SelfType = typeContext->getSelfInterfaceType ();
957+ 
958+         if  (typeContext->getSelfClassDecl () &&
959+             !typeContext->getSelfClassDecl ()->isForeignReferenceType ())
960+           SelfType = DynamicSelfType::get (SelfType, Context);
961+         return  new  (Context)
962+             TypeExpr (new  (Context) SelfTypeRepr (SelfType, Loc));
963+       }
964+     }
965+ 
966+     TypoCorrectionResults corrections (Name, nameLoc);
967+ 
968+     //  FIXME: Don't perform typo correction inside macro arguments, because it
969+     //  will invoke synthesizing declarations in this scope, which will attempt
970+     //  to expand this macro which leads to circular reference errors.
971+     if  (!namelookup::isInMacroArgument (DC->getParentSourceFile (),
972+                                        UDRE->getLoc ())) {
973+       TypeChecker::performTypoCorrection (DC, UDRE->getRefKind (), Type (),
974+                                          lookupOptions, corrections);
975+     }
976+ 
977+     if  (auto  typo = corrections.claimUniqueCorrection ()) {
978+       auto  diag = Context.Diags .diagnose (
979+           Loc, diag::cannot_find_in_scope_corrected, Name, Name.isOperator (),
980+           typo->CorrectedName .getBaseIdentifier ().str ());
981+       diag.highlight (UDRE->getSourceRange ());
982+       typo->addFixits (diag);
983+     } else  {
984+       emitBasicError ();
985+     }
986+ 
987+     corrections.noteAllCandidates ();
988+   } else  {
989+     emitBasicError ();
990+ 
991+     if  (totalCodepoints == 1 ) {
992+       auto  charNames = confusable::getConfusableAndBaseCodepointNames (
993+           firstConfusableCodepoint);
994+       Context.Diags 
995+           .diagnose (Loc, diag::single_confusable_character,
996+                     UDRE->getName ().isOperator (), simpleName.str (),
997+                     charNames.first , expectedIdentifier, charNames.second )
998+           .fixItReplace (Loc, expectedIdentifier);
999+     } else  {
1000+       Context.Diags 
1001+           .diagnose (Loc, diag::confusable_character,
1002+                     UDRE->getName ().isOperator (), simpleName.str (),
1003+                     expectedIdentifier)
1004+           .fixItReplace (Loc, expectedIdentifier);
1005+     }
1006+   }
1007+ 
1008+   //  TODO: consider recovering from here.  We may want some way to suppress
1009+   //  downstream diagnostics, though.
1010+   return  errorResult ();
1011+ }
1012+ 
9861013// / If an expression references 'self.init' or 'super.init' in an
9871014// / initializer context, returns the implicit 'self' decl of the constructor.
9881015// / Otherwise, return nil.
0 commit comments