summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-03-27 12:21:07 -0700
committerGitHub <noreply@github.com>2024-03-27 12:21:07 -0700
commit8395acfa0ad8379011e4470b94362189cafac93f (patch)
tree4395205a3969d2cd3d3b6407fa77786b26aec809 /source
parentc5369d507341e6b6fe64d4e6f26e194cd39235ca (diff)
Fix lookup to prevent finding `typedef` itself. (#3848)
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-ast-support-types.h3
-rw-r--r--source/slang/slang-check-decl.cpp3
-rw-r--r--source/slang/slang-check-expr.cpp7
-rw-r--r--source/slang/slang-check-impl.h10
-rw-r--r--source/slang/slang-lookup.cpp18
-rw-r--r--source/slang/slang-lookup.h6
-rw-r--r--source/slang/slang-parser.cpp11
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();