@@ -351,12 +351,77 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
351351 // name/module qualifier to access top-level name.
352352 lookupOptions |= NameLookupFlags::IncludeOuterResults;
353353
354- if (Loc.isInvalid ())
355- DC = DC->getModuleScopeContext ();
354+ LookupResult Lookup;
356355
357- auto Lookup = TypeChecker::lookupUnqualified (DC, Name, Loc, lookupOptions);
356+ bool AllDeclRefs = true ;
357+ SmallVector<ValueDecl*, 4 > ResultValues;
358358
359359 auto &Context = DC->getASTContext ();
360+ if (Context.LangOpts .DisableParserLookup ) {
361+ // First, look for a local binding in scope.
362+ if (Loc.isValid () && !Name.isOperator ()) {
363+ SmallVector<ValueDecl *, 2 > localDecls;
364+ ASTScope::lookupLocalDecls (DC->getParentSourceFile (),
365+ Name.getFullName (), Loc,
366+ /* stopAfterInnermostBraceStmt=*/ false ,
367+ ResultValues);
368+ for (auto *localDecl : ResultValues) {
369+ Lookup.add (LookupResultEntry (localDecl), /* isOuter=*/ false );
370+ }
371+ }
372+ }
373+
374+ if (!Lookup) {
375+ // Now, look for all local bindings, even forward references, as well
376+ // as type members and top-level declarations.
377+ if (Loc.isInvalid ())
378+ DC = DC->getModuleScopeContext ();
379+
380+ Lookup = TypeChecker::lookupUnqualified (DC, Name, Loc, lookupOptions);
381+
382+ ValueDecl *localDeclAfterUse = nullptr ;
383+ auto isValid = [&](ValueDecl *D) {
384+ // If we find something in the current context, it must be a forward
385+ // reference, because otherwise if it was in scope, it would have
386+ // been returned by the call to ASTScope::lookupLocalDecls() above.
387+ if (D->getDeclContext ()->isLocalContext () &&
388+ D->getDeclContext () == DC &&
389+ (Context.LangOpts .DisableParserLookup ||
390+ (Loc.isValid () && D->getLoc ().isValid () &&
391+ Context.SourceMgr .isBeforeInBuffer (Loc, D->getLoc ()) &&
392+ !isa<TypeDecl>(D)))) {
393+ localDeclAfterUse = D;
394+ return false ;
395+ }
396+ return true ;
397+ };
398+ AllDeclRefs =
399+ findNonMembers (Lookup.innerResults (), UDRE->getRefKind (),
400+ /* breakOnMember=*/ true , ResultValues, isValid);
401+
402+ // If local declaration after use is found, check outer results for
403+ // better matching candidates.
404+ if (ResultValues.empty () && localDeclAfterUse) {
405+ auto innerDecl = localDeclAfterUse;
406+ while (localDeclAfterUse) {
407+ if (Lookup.outerResults ().empty ()) {
408+ Context.Diags .diagnose (Loc, diag::use_local_before_declaration, Name);
409+ Context.Diags .diagnose (innerDecl, diag::decl_declared_here,
410+ localDeclAfterUse->getName ());
411+ Expr *error = new (Context) ErrorExpr (UDRE->getSourceRange ());
412+ return error;
413+ }
414+
415+ Lookup.shiftDownResults ();
416+ ResultValues.clear ();
417+ localDeclAfterUse = nullptr ;
418+ AllDeclRefs =
419+ findNonMembers (Lookup.innerResults (), UDRE->getRefKind (),
420+ /* breakOnMember=*/ true , ResultValues, isValid);
421+ }
422+ }
423+ }
424+
360425 if (!Lookup) {
361426 // If we failed lookup of an operator, check to see if this is a range
362427 // operator misspelling. Otherwise try to diagnose a juxtaposition
@@ -487,50 +552,6 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
487552
488553 // FIXME: Need to refactor the way we build an AST node from a lookup result!
489554
490- SmallVector<ValueDecl*, 4 > ResultValues;
491- ValueDecl *localDeclAfterUse = nullptr ;
492- auto isValid = [&](ValueDecl *D) {
493- // FIXME: The source-location checks won't make sense once
494- // EnableASTScopeLookup is the default.
495- //
496- // Note that we allow forward references to types, because they cannot
497- // capture.
498- if (Loc.isValid () && D->getLoc ().isValid () &&
499- D->getDeclContext ()->isLocalContext () &&
500- D->getDeclContext () == DC &&
501- Context.SourceMgr .isBeforeInBuffer (Loc, D->getLoc ()) &&
502- !isa<TypeDecl>(D)) {
503- localDeclAfterUse = D;
504- return false ;
505- }
506- return true ;
507- };
508- bool AllDeclRefs =
509- findNonMembers (Lookup.innerResults (), UDRE->getRefKind (),
510- /* breakOnMember=*/ true , ResultValues, isValid);
511-
512- // If local declaration after use is found, check outer results for
513- // better matching candidates.
514- if (localDeclAfterUse) {
515- auto innerDecl = localDeclAfterUse;
516- while (localDeclAfterUse) {
517- if (Lookup.outerResults ().empty ()) {
518- Context.Diags .diagnose (Loc, diag::use_local_before_declaration, Name);
519- Context.Diags .diagnose (innerDecl, diag::decl_declared_here,
520- localDeclAfterUse->getName ());
521- Expr *error = new (Context) ErrorExpr (UDRE->getSourceRange ());
522- return error;
523- }
524-
525- Lookup.shiftDownResults ();
526- ResultValues.clear ();
527- localDeclAfterUse = nullptr ;
528- AllDeclRefs =
529- findNonMembers (Lookup.innerResults (), UDRE->getRefKind (),
530- /* breakOnMember=*/ true , ResultValues, isValid);
531- }
532- }
533-
534555 // If we have an unambiguous reference to a type decl, form a TypeExpr.
535556 if (Lookup.size () == 1 && UDRE->getRefKind () == DeclRefKind::Ordinary &&
536557 isa<TypeDecl>(Lookup[0 ].getValueDecl ())) {
0 commit comments