summaryrefslogtreecommitdiff
path: root/source/slang/slang-check-modifier.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-12-06 12:05:07 -0800
committerGitHub <noreply@github.com>2023-12-06 12:05:07 -0800
commit11111e5733b189127dc2c4934d67693b9bc6e764 (patch)
tree0ba84df3e856eb104abec2ecac47242bc70a7b7d /source/slang/slang-check-modifier.cpp
parentfa6d8717d02912697c09f2d7de802723ac6d6e47 (diff)
Support visibility control and default to `internal`. (#3380)
* Support visibility control and default to `internal`. * Fix wip. * Fixes. * Fix. * Fix test. * Add legacy language detection and compatibility for existing code. * Add doc. --------- Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-check-modifier.cpp')
-rw-r--r--source/slang/slang-check-modifier.cpp84
1 files changed, 83 insertions, 1 deletions
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index 569804ff4..339ecba4c 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -950,7 +950,7 @@ namespace Slang
{
if (auto parentExtension = as<ExtensionDecl>(varDecl->parentDecl))
{
- auto originalMemberLookup = lookUpMember(m_astBuilder, this, varDecl->getName(), parentExtension->targetType);
+ auto originalMemberLookup = lookUpMember(m_astBuilder, this, varDecl->getName(), parentExtension->targetType, parentExtension->ownedScope);
LookupResult filteredResult;
for (auto item : originalMemberLookup.items)
{
@@ -1042,6 +1042,23 @@ namespace Slang
}
}
+ if (as<PrivateModifier>(m))
+ {
+ if (as<AggTypeDeclBase>(syntaxNode) || as<NamespaceDeclBase>(syntaxNode))
+ {
+ getSink()->diagnose(m, Diagnostics::invalidUseOfPrivateVisibility, as<Decl>(syntaxNode));
+ }
+ else if (auto decl = as<Decl>(syntaxNode))
+ {
+ // Interface requirements can't be private.
+ if (isInterfaceRequirement(decl))
+ {
+ getSink()->diagnose(m, Diagnostics::invalidUseOfPrivateVisibility, as<Decl>(syntaxNode));
+ }
+ }
+ }
+
+
// Default behavior is to leave things as they are,
// and assume that modifiers are mostly already checked.
//
@@ -1054,6 +1071,71 @@ namespace Slang
return m;
}
+ void SemanticsVisitor::checkVisibility(Decl* decl)
+ {
+ if (as<AccessorDecl>(decl))
+ {
+ return;
+ }
+ ShortList<Type*> typesToVerify;
+ if (auto varDecl = as<VarDeclBase>(decl))
+ {
+ typesToVerify.add(varDecl->type);
+ }
+ else if (auto callable = as<CallableDecl>(decl))
+ {
+ typesToVerify.add(callable->returnType);
+ typesToVerify.add(callable->errorType);
+ for (auto param : callable->getParameters())
+ {
+ typesToVerify.add(param->type);
+ }
+ }
+ else if (auto propertyDecl = as<PropertyDecl>(decl))
+ {
+ typesToVerify.add(propertyDecl->type);
+ }
+ else if (as<AggTypeDeclBase>(decl))
+ {
+ }
+ else if (auto typeDecl = as<TypeDefDecl>(decl))
+ {
+ typesToVerify.add(typeDecl->type);
+ }
+ else
+ {
+ return;
+ }
+ auto thisVisibility = getDeclVisibility(decl);
+
+ // First, we check that the decl's type does not have lower visibility.
+ for (auto type : typesToVerify)
+ {
+ if (!type)
+ continue;
+ DeclVisibility typeVisibility = getTypeVisibility(type);
+ if (typeVisibility < thisVisibility)
+ {
+ getSink()->diagnose(decl, Diagnostics::useOfLessVisibleType, decl, type);
+ break;
+ }
+ }
+
+ // Next, we check that the decl does not have higher visiblity than its parent.
+ Decl* parentDecl = decl;
+ for (; parentDecl; parentDecl = parentDecl->parentDecl)
+ {
+ if (as<AggTypeDeclBase>(parentDecl))
+ break;
+ }
+ if (!parentDecl)
+ return;
+ auto parentVisibility = getDeclVisibility(parentDecl);
+ if (thisVisibility > parentVisibility)
+ {
+ getSink()->diagnose(decl, Diagnostics::declCannotHaveHigherVisibility, decl, parentDecl);
+ }
+ }
void SemanticsVisitor::checkModifiers(ModifiableSyntaxNode* syntaxNode)
{