diff options
| author | Yong He <yonghe@outlook.com> | 2024-03-27 12:21:07 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-27 12:21:07 -0700 |
| commit | 8395acfa0ad8379011e4470b94362189cafac93f (patch) | |
| tree | 4395205a3969d2cd3d3b6407fa77786b26aec809 /source | |
| parent | c5369d507341e6b6fe64d4e6f26e194cd39235ca (diff) | |
Fix lookup to prevent finding `typedef` itself. (#3848)
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-ast-support-types.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 7 | ||||
| -rw-r--r-- | source/slang/slang-check-impl.h | 10 | ||||
| -rw-r--r-- | source/slang/slang-lookup.cpp | 18 | ||||
| -rw-r--r-- | source/slang/slang-lookup.h | 6 | ||||
| -rw-r--r-- | source/slang/slang-parser.cpp | 11 |
7 files changed, 45 insertions, 13 deletions
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h index e4e3be384..196a1d002 100644 --- a/source/slang/slang-ast-support-types.h +++ b/source/slang/slang-ast-support-types.h @@ -1421,6 +1421,9 @@ namespace Slang Scope* scope = nullptr; Scope* endScope = nullptr; + // A decl to exclude from the lookup, used to exclude the current decl being checked, such as in typedef Foo Foo; + // to avoid finding itself. + Decl* declToExclude = nullptr; LookupMask mask = LookupMask::Default; LookupOptions options = LookupOptions::None; diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index c844fb82a..ed97e412d 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -6203,7 +6203,8 @@ namespace Slang void SemanticsDeclHeaderVisitor::visitTypeDefDecl(TypeDefDecl* decl) { - decl->type = CheckProperType(decl->type); + SemanticsVisitor visitor(withDeclToExcludeFromLookup(decl)); + decl->type = visitor.CheckProperType(decl->type); checkVisibility(decl); } diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index a31e17123..ad6bb2a86 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -2601,8 +2601,7 @@ namespace Slang } expr->type = QualType(m_astBuilder->getErrorType()); auto lookupResult = lookUp( - m_astBuilder, - this, expr->name, expr->scope); + m_astBuilder, this, expr->name, expr->scope, LookupMask::Default, false, getDeclToExcludeFromLookup()); bool diagnosed = false; lookupResult = filterLookupResultByVisibilityAndDiagnose(lookupResult, expr->loc, diagnosed); @@ -3703,7 +3702,9 @@ namespace Slang this, expr->name, namespaceDecl, - DeclRef(namespaceDecl)); + DeclRef(namespaceDecl), + LookupMask::Default, + getDeclToExcludeFromLookup()); AddToLookupResult(globalLookupResult, nsLookupResult); } } diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h index 278fc3265..a3ecc28b4 100644 --- a/source/slang/slang-check-impl.h +++ b/source/slang/slang-check-impl.h @@ -921,6 +921,15 @@ namespace Slang return result; } + SemanticsContext withDeclToExcludeFromLookup(Decl* decl) + { + SemanticsContext result(*this); + result.m_declToExcludeFromLookup = decl; + return result; + } + + Decl* getDeclToExcludeFromLookup() { return m_declToExcludeFromLookup; } + private: SharedSemanticsContext* m_shared = nullptr; @@ -928,6 +937,7 @@ namespace Slang ExprLocalScope* m_exprLocalScope = nullptr; + Decl* m_declToExcludeFromLookup = nullptr; protected: // TODO: consider making more of this state `private`... diff --git a/source/slang/slang-lookup.cpp b/source/slang/slang-lookup.cpp index 301c86aa8..6a62303d2 100644 --- a/source/slang/slang-lookup.cpp +++ b/source/slang/slang-lookup.cpp @@ -213,6 +213,8 @@ static void _lookUpDirectAndTransparentMembers( // it's unchecked or being checked then it isn't declared yet. if(!request.shouldConsiderAllLocalNames() && request.semantics && _isUncheckedLocalVar(m)) continue; + if (m == request.declToExclude) + continue; if (!DeclPassesLookupMask(m, request.mask)) continue; @@ -253,13 +255,15 @@ LookupRequest initLookupRequest( Name* name, LookupMask mask, LookupOptions options, - Scope* scope) + Scope* scope, + Decl* declToExclude) { LookupRequest request; request.semantics = semantics; request.mask = mask; request.options = options; request.scope = scope; + request.declToExclude = declToExclude; if (semantics && semantics->getSession() && name == semantics->getSession()->getCompletionRequestTokenName()) @@ -275,9 +279,10 @@ LookupResult lookUpDirectAndTransparentMembers( Name* name, ContainerDecl* containerDecl, DeclRef<Decl> parentDeclRef, - LookupMask mask) + LookupMask mask, + Decl* declToExclude) { - LookupRequest request = initLookupRequest(semantics, name, mask, LookupOptions::None, nullptr); + LookupRequest request = initLookupRequest(semantics, name, mask, LookupOptions::None, nullptr, declToExclude); LookupResult result; _lookUpDirectAndTransparentMembers( astBuilder, @@ -892,13 +897,14 @@ LookupResult lookUp( Name* name, Scope* scope, LookupMask mask, - bool considerAllLocalNamesInScope) + bool considerAllLocalNamesInScope, + Decl* declToExclude) { LookupResult result; const auto options = considerAllLocalNamesInScope ? LookupOptions::ConsiderAllLocalNamesInScope : LookupOptions::None; - LookupRequest request = initLookupRequest(semantics, name, mask, options, scope); + LookupRequest request = initLookupRequest(semantics, name, mask, options, scope, declToExclude); _lookUpInScopes(astBuilder, name, request, result); return result; } @@ -913,7 +919,7 @@ LookupResult lookUpMember( LookupOptions options) { LookupResult result; - LookupRequest request = initLookupRequest(semantics, name, mask, options, sourceScope); + LookupRequest request = initLookupRequest(semantics, name, mask, options, sourceScope, nullptr); _lookUpMembersInType(astBuilder, name, type, request, result, nullptr); return result; } diff --git a/source/slang/slang-lookup.h b/source/slang/slang-lookup.h index 84b453bf2..fb7511428 100644 --- a/source/slang/slang-lookup.h +++ b/source/slang/slang-lookup.h @@ -19,7 +19,8 @@ LookupResult lookUp( Name* name, Scope* scope, LookupMask mask = LookupMask::Default, - bool considerAllLocalNamesInScope = false); + bool considerAllLocalNamesInScope = false, + Decl* declToExclude = nullptr); // Perform member lookup in the context of a type LookupResult lookUpMember( @@ -38,7 +39,8 @@ LookupResult lookUpDirectAndTransparentMembers( Name* name, ContainerDecl* containerDecl, DeclRef<Decl> parentDeclRef, // The parent of the resulting declref. - LookupMask mask = LookupMask::Default); + LookupMask mask = LookupMask::Default, + Decl* declToExclude = nullptr); // TODO: this belongs somewhere else diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index b99df18e4..cc3a661f3 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -2576,11 +2576,20 @@ namespace Slang typeSpec.expr = parseFuncTypeExpr(parser); return typeSpec; } + + bool inGlobalScope = false; + if (AdvanceIf(parser, TokenType::Scope)) + { + inGlobalScope = true; + } Token typeName = parser->ReadToken(TokenType::Identifier); auto basicType = parser->astBuilder->create<VarExpr>(); - basicType->scope = parser->currentLookupScope; + if (inGlobalScope) + basicType->scope = parser->currentModule->ownedScope; + else + basicType->scope = parser->currentLookupScope; basicType->loc = typeName.loc; basicType->name = typeName.getNameOrNull(); |
