summaryrefslogtreecommitdiffstats
path: root/source/slang/check.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-03-06 20:16:20 -0500
committerTim Foley <tfoleyNV@users.noreply.github.com>2019-03-06 17:16:20 -0800
commitc850ba44164ac2bee895137abdd184beb4123090 (patch)
treef6e42ce5998038a1162e95c2a879bb7b06d0573f /source/slang/check.cpp
parent87610f6def3e3dceac0082c1b60abbe2aee09014 (diff)
* Add support for enum and type lookup via :: (scope operator) (#882)
* Added test for scope operator
Diffstat (limited to 'source/slang/check.cpp')
-rw-r--r--source/slang/check.cpp162
1 files changed, 98 insertions, 64 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index 37c0d5baf..91bbd694a 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -8843,63 +8843,14 @@ namespace Slang
}
}
- RefPtr<Expr> visitStaticMemberExpr(StaticMemberExpr* /*expr*/)
+ // Look up a static member
+ // @param expr Can be StaticMemberExpr or MemberExpr
+ // @param baseExpression Is the underlying type expression determined from resolving expr
+ RefPtr<Expr> _lookupStaticMember(RefPtr<DeclRefExpr> expr, RefPtr<Expr> baseExpression)
{
- // StaticMemberExpr means it is already checked
- SLANG_UNEXPECTED("should not occur in unchecked AST");
- UNREACHABLE_RETURN(nullptr);
- }
-
- RefPtr<Expr> lookupResultFailure(
- MemberExpr* expr,
- QualType const& baseType)
- {
- getSink()->diagnose(expr, Diagnostics::noMemberOfNameInType, expr->name, baseType);
- expr->type = QualType(getSession()->getErrorType());
- return expr;
-
- }
-
- RefPtr<Expr> visitMemberExpr(MemberExpr * expr)
- {
- expr->BaseExpression = CheckExpr(expr->BaseExpression);
-
- expr->BaseExpression = MaybeDereference(expr->BaseExpression);
+ auto& baseType = baseExpression->type;
- // If the base of the member lookup has an interface type
- // *without* a suitable this-type substitution, then we are
- // trying to perform lookup on a value of existential type,
- // and we should "open" the existential here so that we
- // can expose its structure.
- //
- expr->BaseExpression = maybeOpenExistential(expr->BaseExpression);
-
- auto & baseType = expr->BaseExpression->type;
-
- // Note: Checking for vector types before declaration-reference types,
- // because vectors are also declaration reference types...
- //
- // Also note: the way this is done right now means that the ability
- // to swizzle vectors interferes with any chance of looking up
- // members via extension, for vector or scalar types.
- //
- // TODO: Matrix swizzles probably need to be handled at some point.
- if (auto baseVecType = as<VectorExpressionType>(baseType))
- {
- return CheckSwizzleExpr(
- expr,
- baseVecType->elementType,
- baseVecType->elementCount);
- }
- else if(auto baseScalarType = as<BasicExpressionType>(baseType))
- {
- // Treat scalar like a 1-element vector when swizzling
- return CheckSwizzleExpr(
- expr,
- baseScalarType,
- 1);
- }
- else if(auto typeType = as<TypeType>(baseType))
+ if (auto typeType = as<TypeType>(baseType))
{
// We are looking up a member inside a type.
// We want to be careful here because we should only find members
@@ -8921,7 +8872,7 @@ namespace Slang
type);
if (!lookupResult.isValid())
{
- return lookupResultFailure(expr, baseType);
+ return lookupMemberResultFailure(expr, baseType);
}
// We need to confirm that whatever member we
@@ -8947,13 +8898,13 @@ namespace Slang
// For now let's just be expedient and disallow all of that, because
// we can always add it back in later.
- if(!lookupResult.isOverloaded())
+ if (!lookupResult.isOverloaded())
{
// The non-overloaded case is relatively easy. We just want
// to look at the member being referenced, and check if
// it is allowed in a `static` context:
//
- if(!isUsableAsStaticMember(lookupResult.item))
+ if (!isUsableAsStaticMember(lookupResult.item))
{
getSink()->diagnose(
expr->loc,
@@ -8972,10 +8923,10 @@ namespace Slang
// are non-static.
bool anyNonStatic = false;
List<LookupResultItem> staticItems;
- for(auto item : lookupResult.items)
+ for (auto item : lookupResult.items)
{
// Is this item usable as a static member?
- if(isUsableAsStaticMember(item))
+ if (isUsableAsStaticMember(item))
{
// If yes, then it will be part of the output.
staticItems.Add(item);
@@ -8988,11 +8939,11 @@ namespace Slang
}
// Was there anything non-static in the list?
- if(anyNonStatic)
+ if (anyNonStatic)
{
// If we had some static items, then that's okay,
// we just want to use our newly-filtered list.
- if(staticItems.Count())
+ if (staticItems.Count())
{
lookupResult.items = staticItems;
}
@@ -9012,13 +8963,96 @@ namespace Slang
return createLookupResultExpr(
lookupResult,
- expr->BaseExpression,
+ baseExpression,
expr->loc);
}
else if (as<ErrorType>(baseType))
{
return CreateErrorExpr(expr);
}
+
+ // Failure
+ return lookupMemberResultFailure(expr, baseType);
+ }
+
+ RefPtr<Expr> visitStaticMemberExpr(StaticMemberExpr* expr)
+ {
+ expr->BaseExpression = CheckExpr(expr->BaseExpression);
+
+ // Not sure this is needed -> but guess someone could do
+ expr->BaseExpression = MaybeDereference(expr->BaseExpression);
+
+ // If the base of the member lookup has an interface type
+ // *without* a suitable this-type substitution, then we are
+ // trying to perform lookup on a value of existential type,
+ // and we should "open" the existential here so that we
+ // can expose its structure.
+ //
+
+ expr->BaseExpression = maybeOpenExistential(expr->BaseExpression);
+ // Do a static lookup
+ return _lookupStaticMember(expr, expr->BaseExpression);
+ }
+
+ RefPtr<Expr> lookupMemberResultFailure(
+ DeclRefExpr* expr,
+ QualType const& baseType)
+ {
+ // Check it's a member expression
+ SLANG_ASSERT(as<StaticMemberExpr>(expr) || as<MemberExpr>(expr));
+
+ getSink()->diagnose(expr, Diagnostics::noMemberOfNameInType, expr->name, baseType);
+ expr->type = QualType(getSession()->getErrorType());
+ return expr;
+ }
+
+ RefPtr<Expr> visitMemberExpr(MemberExpr * expr)
+ {
+ expr->BaseExpression = CheckExpr(expr->BaseExpression);
+
+ expr->BaseExpression = MaybeDereference(expr->BaseExpression);
+
+ // If the base of the member lookup has an interface type
+ // *without* a suitable this-type substitution, then we are
+ // trying to perform lookup on a value of existential type,
+ // and we should "open" the existential here so that we
+ // can expose its structure.
+ //
+ expr->BaseExpression = maybeOpenExistential(expr->BaseExpression);
+
+ auto & baseType = expr->BaseExpression->type;
+
+ // Note: Checking for vector types before declaration-reference types,
+ // because vectors are also declaration reference types...
+ //
+ // Also note: the way this is done right now means that the ability
+ // to swizzle vectors interferes with any chance of looking up
+ // members via extension, for vector or scalar types.
+ //
+ // TODO: Matrix swizzles probably need to be handled at some point.
+ if (auto baseVecType = as<VectorExpressionType>(baseType))
+ {
+ return CheckSwizzleExpr(
+ expr,
+ baseVecType->elementType,
+ baseVecType->elementCount);
+ }
+ else if(auto baseScalarType = as<BasicExpressionType>(baseType))
+ {
+ // Treat scalar like a 1-element vector when swizzling
+ return CheckSwizzleExpr(
+ expr,
+ baseScalarType,
+ 1);
+ }
+ else if(auto typeType = as<TypeType>(baseType))
+ {
+ return _lookupStaticMember(expr, expr->BaseExpression);
+ }
+ else if (as<ErrorType>(baseType))
+ {
+ return CreateErrorExpr(expr);
+ }
else
{
LookupResult lookupResult = lookUpMember(
@@ -9028,7 +9062,7 @@ namespace Slang
baseType.Ptr());
if (!lookupResult.isValid())
{
- return lookupResultFailure(expr, baseType);
+ return lookupMemberResultFailure(expr, baseType);
}
// TODO: need to filter for declarations that are valid to refer