diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-02-02 11:58:54 -0500 |
|---|---|---|
| committer | Tim Foley <tfoleyNV@users.noreply.github.com> | 2019-02-02 08:58:54 -0800 |
| commit | 3726194fbe3da234eb30b6371e5b4ab1ea388f93 (patch) | |
| tree | 815bb6162f76aeb2bd517126b802cc511cd0322a /source | |
| parent | 6f2c03430afdf963eed53c08d0b63342af722868 (diff) | |
Feature/as refactor review (#821)
* Replace dynamicCast with as where does not change behavior (ie not Type derived).
Use free function where scoping is clear.
* Replace uses of dynamicCast with as when there is no difference in behavior.
* Remove the IsXXXX methods from Type.
* Don't have separate smart pointer to store canonicalType on Type.
* Simplify Slang.FilteredMemberRefList.Adjust, such does the cast directly.
* Use free as where appropriate.
* Use free function version of casts where appropriate.
* Fix text in casting.md
* Fix typos in decl-refs.md
* Remove the uses of free function as on RefDecl.
Add 'canAs' to RefDecl as a way to test if a cast is possible.
Moved 'as' into RefDeclBase.
* Use 'is' to test for as cast on smart pointers.
Fix small scope issue.
* * Cache stringType and enumTypeType on the Session
* Make DeclRefType::Create return a RefPtr
* Make casting of result use the *method* .as (cos using free function would mean objects being wrongly destroyed)
* Make results from createInstance ref'd to avoid possible leaks.
* Fix typo in template parameter for is on RefPtr.
Diffstat (limited to 'source')
| -rw-r--r-- | source/core/smart-pointer.h | 3 | ||||
| -rw-r--r-- | source/slang/check.cpp | 112 | ||||
| -rw-r--r-- | source/slang/compiler.h | 3 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 8 | ||||
| -rw-r--r-- | source/slang/ir-entry-point-uniforms.cpp | 2 | ||||
| -rw-r--r-- | source/slang/ir-legalize-types.cpp | 2 | ||||
| -rw-r--r-- | source/slang/legalize-types.h | 6 | ||||
| -rw-r--r-- | source/slang/lookup.cpp | 3 | ||||
| -rw-r--r-- | source/slang/mangle.cpp | 16 | ||||
| -rw-r--r-- | source/slang/parameter-binding.cpp | 14 | ||||
| -rw-r--r-- | source/slang/parser.cpp | 4 | ||||
| -rw-r--r-- | source/slang/reflection.cpp | 8 | ||||
| -rw-r--r-- | source/slang/syntax-base-defs.h | 19 | ||||
| -rw-r--r-- | source/slang/syntax.cpp | 153 | ||||
| -rw-r--r-- | source/slang/syntax.h | 45 | ||||
| -rw-r--r-- | source/slang/type-defs.h | 2 |
16 files changed, 207 insertions, 193 deletions
diff --git a/source/core/smart-pointer.h b/source/core/smart-pointer.h index d026388c0..e19ed6a4d 100644 --- a/source/core/smart-pointer.h +++ b/source/core/smart-pointer.h @@ -194,6 +194,9 @@ namespace Slang return RefPtr<U>(Slang::as<U>(pointer)); } + template <typename U> + bool is() const { return Slang::as<U>(pointer) != nullptr; } + ~RefPtr() { releaseReference((Slang::RefObject*) pointer); diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 199e733ce..d1294841c 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -126,7 +126,7 @@ namespace Slang } else if (auto vectorType = as<VectorExpressionType>(typeIn)) { - if (auto elemCount = vectorType->elementCount.dynamicCast<ConstantIntVal>()) + if (auto elemCount = as<ConstantIntVal>(vectorType->elementCount)) { data.dim1 = elemCount->value - 1; auto elementBasicType = as<BasicExpressionType>(vectorType->elementType); @@ -583,7 +583,7 @@ namespace Slang // to the chosen interface decl must be the first substitution on // the list (which is a linked list from the "inside" out). // - auto thisTypeSubst = interfaceDeclRef.substitutions.substitutions.dynamicCast<ThisTypeSubstitution>(); + auto thisTypeSubst = interfaceDeclRef.substitutions.substitutions.as<ThisTypeSubstitution>(); if(thisTypeSubst && thisTypeSubst->interfaceDecl == interfaceDeclRef.decl) { // This isn't really an existential type, because somebody @@ -885,16 +885,16 @@ namespace Slang RefPtr<Expr> ExpectATypeRepr(RefPtr<Expr> expr) { - if (auto overloadedExpr = expr.dynamicCast<OverloadedExpr>()) + if (auto overloadedExpr = as<OverloadedExpr>(expr)) { expr = ResolveOverloadedExpr(overloadedExpr, LookupMask::type); } - if (auto typeType = as<TypeType>(expr->type.type)) + if (auto typeType = as<TypeType>(expr->type)) { return expr; } - else if (auto errorType = as<ErrorType>(expr->type.type)) + else if (auto errorType = as<ErrorType>(expr->type)) { return expr; } @@ -925,7 +925,7 @@ namespace Slang RefPtr<Val> ExtractGenericArgVal(RefPtr<Expr> exp) { - if (auto overloadedExpr = exp.dynamicCast<OverloadedExpr>()) + if (auto overloadedExpr = as<OverloadedExpr>(exp)) { // assume that if it is overloaded, we want a type exp = ResolveOverloadedExpr(overloadedExpr, LookupMask::type); @@ -1043,7 +1043,7 @@ namespace Slang // this is a quick fix that at least alerts the user to how we are // interpreting their code. // - if (auto varDecl = decl.dynamicCast<VarDecl>()) + if (auto varDecl = as<VarDecl>(decl)) { if (auto parenScope = as<ScopeDecl>(varDecl->ParentDecl)) { @@ -1076,7 +1076,7 @@ namespace Slang void EnusreAllDeclsRec(RefPtr<Decl> decl) { checkDecl(decl); - if (auto containerDecl = decl.dynamicCast<ContainerDecl>()) + if (auto containerDecl = as<ContainerDecl>(decl)) { for (auto m : containerDecl->Members) { @@ -1111,7 +1111,7 @@ namespace Slang Type* type = typeExp.type.Ptr(); if(!type && typeExp.exp) { - if(auto typeType = typeExp.exp->type.type.dynamicCast<TypeType>()) + if(auto typeType = as<TypeType>(typeExp.exp->type)) { type = typeType->type; } @@ -1141,7 +1141,7 @@ namespace Slang List<RefPtr<Expr>> args; for (RefPtr<Decl> member : genericDeclRef.getDecl()->Members) { - if (auto typeParam = member.dynamicCast<GenericTypeParamDecl>()) + if (auto typeParam = as<GenericTypeParamDecl>(member)) { if (!typeParam->initType.exp) { @@ -1157,7 +1157,7 @@ namespace Slang if (outProperType) args.Add(typeParam->initType.exp); } - else if (auto valParam = member.dynamicCast<GenericValueParamDecl>()) + else if (auto valParam = as<GenericValueParamDecl>(member)) { if (!valParam->initExpr) { @@ -1274,11 +1274,11 @@ namespace Slang // Capture the "base" expression in case this is a member reference RefPtr<Expr> GetBaseExpr(RefPtr<Expr> expr) { - if (auto memberExpr = expr.dynamicCast<MemberExpr>()) + if (auto memberExpr = as<MemberExpr>(expr)) { return memberExpr->BaseExpression; } - else if(auto overloadedExpr = expr.dynamicCast<OverloadedExpr>()) + else if(auto overloadedExpr = as<OverloadedExpr>(expr)) { return overloadedExpr->base; } @@ -1293,17 +1293,17 @@ namespace Slang { if(left == right) return true; - if(auto leftConst = left.dynamicCast<ConstantIntVal>()) + if(auto leftConst = as<ConstantIntVal>(left)) { - if(auto rightConst = right.dynamicCast<ConstantIntVal>()) + if(auto rightConst = as<ConstantIntVal>(right)) { return leftConst->value == rightConst->value; } } - if(auto leftVar = left.dynamicCast<GenericParamIntVal>()) + if(auto leftVar = as<GenericParamIntVal>(left)) { - if(auto rightVar = right.dynamicCast<GenericParamIntVal>()) + if(auto rightVar = as<GenericParamIntVal>(right)) { return leftVar->declRef.Equals(rightVar->declRef); } @@ -1352,7 +1352,7 @@ namespace Slang if(auto declRefType = as<DeclRefType>(type)) { - if(declRefType->declRef.as<StructDecl>()) + if(as<StructDecl>(declRefType->declRef)) return false; } @@ -1366,7 +1366,7 @@ namespace Slang { // A nested initializer list should always be used directly. // - if(fromExpr.dynamicCast<InitializerListExpr>()) + if(as<InitializerListExpr>(fromExpr)) { return true; } @@ -1500,7 +1500,7 @@ namespace Slang auto toElementType = toVecType->elementType; UInt elementCount = 0; - if (auto constElementCount = toElementCount.dynamicCast<ConstantIntVal>()) + if (auto constElementCount = as<ConstantIntVal>(toElementCount)) { elementCount = (UInt) constElementCount->value; } @@ -1548,7 +1548,7 @@ namespace Slang // of elements being initialized matches what was declared. // UInt elementCount = 0; - if (auto constElementCount = toElementCount.dynamicCast<ConstantIntVal>()) + if (auto constElementCount = as<ConstantIntVal>(toElementCount)) { elementCount = (UInt) constElementCount->value; } @@ -1780,7 +1780,7 @@ namespace Slang } // Coercion from an initializer list is allowed for many types - if( auto fromInitializerListExpr = fromExpr.dynamicCast<InitializerListExpr>()) + if( auto fromInitializerListExpr = as<InitializerListExpr>(fromExpr)) { if(!tryCoerceInitializerList(toType, outToExpr, fromInitializerListExpr)) return false; @@ -2210,14 +2210,15 @@ namespace Slang } // Fill in default substitutions for the 'subtype' part of a type constraint decl - void CheckConstraintSubType(TypeExp & typeExp) + void CheckConstraintSubType(TypeExp& typeExp) { - if (auto sharedTypeExpr = typeExp.exp.dynamicCast<SharedTypeExpr>()) + if (auto sharedTypeExpr = as<SharedTypeExpr>(typeExp.exp)) { if (auto declRefType = as<DeclRefType>(sharedTypeExpr->base)) { declRefType->declRef.substitutions = createDefaultSubstitutions(getSession(), declRefType->declRef.getDecl()); - if (auto typetype = typeExp.exp->type.type.dynamicCast<TypeType>()) + + if (auto typetype = as<TypeType>(typeExp.exp->type)) typetype->type = declRefType; } } @@ -2707,8 +2708,9 @@ namespace Slang return uncheckedAttr; } - RefPtr<RefObject> attrObj = attrDecl->syntaxClass.createInstance(); - auto attr = attrObj.dynamicCast<Attribute>(); + // Manage scope + RefPtr<RefObject> attrInstance = attrDecl->syntaxClass.createInstance(); + auto attr = attrInstance.as<Attribute>(); if(!attr) { SLANG_DIAGNOSE_UNEXPECTED(getSink(), attrDecl, "attribute class did not yield an attribute object"); @@ -2802,7 +2804,7 @@ namespace Slang RefPtr<Modifier> m, ModifiableSyntaxNode* syntaxNode) { - if(auto hlslUncheckedAttribute = m.dynamicCast<UncheckedAttribute>()) + if(auto hlslUncheckedAttribute = as<UncheckedAttribute>(m)) { // We have an HLSL `[name(arg,...)]` attribute, and we'd like // to check that it is provides all the expected arguments @@ -3036,17 +3038,17 @@ namespace Slang { auto genMbr = genDecl.getDecl()->Members[i]; auto requiredGenMbr = genDecl.getDecl()->Members[i]; - if (auto genTypeMbr = genMbr.dynamicCast<GenericTypeParamDecl>()) + if (auto genTypeMbr = as<GenericTypeParamDecl>(genMbr)) { - if (auto requiredGenTypeMbr = requiredGenMbr.dynamicCast<GenericTypeParamDecl>()) + if (auto requiredGenTypeMbr = as<GenericTypeParamDecl>(requiredGenMbr)) { } else return false; } - else if (auto genValMbr = genMbr.dynamicCast<GenericValueParamDecl>()) + else if (auto genValMbr = as<GenericValueParamDecl>(genMbr)) { - if (auto requiredGenValMbr = requiredGenMbr.dynamicCast<GenericValueParamDecl>()) + if (auto requiredGenValMbr = as<GenericValueParamDecl>(requiredGenMbr)) { if (!genValMbr->type->Equals(requiredGenValMbr->type)) return false; @@ -3054,9 +3056,9 @@ namespace Slang else return false; } - else if (auto genTypeConstraintMbr = genMbr.dynamicCast<GenericTypeConstraintDecl>()) + else if (auto genTypeConstraintMbr = as<GenericTypeConstraintDecl>(genMbr)) { - if (auto requiredTypeConstraintMbr = requiredGenMbr.dynamicCast<GenericTypeConstraintDecl>()) + if (auto requiredTypeConstraintMbr = as<GenericTypeConstraintDecl>(requiredGenMbr)) { if (!genTypeConstraintMbr->sup->Equals(requiredTypeConstraintMbr->sup)) { @@ -3844,7 +3846,7 @@ namespace Slang RefPtr<IntVal> explicitTagVal = TryConstantFoldExpr(explicitTagValExpr); if(explicitTagVal) { - if(auto constIntVal = explicitTagVal.dynamicCast<ConstantIntVal>()) + if(auto constIntVal = as<ConstantIntVal>(explicitTagVal)) { defaultTag = constIntVal->value; } @@ -4895,7 +4897,7 @@ namespace Slang // // For right now we will look for calls to intrinsic functions, and then inspect // their names (this is bad and slow). - auto funcDeclRefExpr = invokeExpr->FunctionExpr.dynamicCast<DeclRefExpr>(); + auto funcDeclRefExpr = invokeExpr->FunctionExpr.as<DeclRefExpr>(); if (!funcDeclRefExpr) return nullptr; auto funcDeclRef = funcDeclRefExpr->declRef; @@ -5197,7 +5199,7 @@ namespace Slang { auto session = getSession(); auto vectorGenericDecl = findMagicDecl( - session, "Vector").dynamicCast<GenericDecl>(); + session, "Vector").as<GenericDecl>(); auto vectorTypeDecl = vectorGenericDecl->inner; auto substitutions = new GenericSubstitution(); @@ -5207,9 +5209,9 @@ namespace Slang auto declRef = DeclRef<Decl>(vectorTypeDecl.Ptr(), substitutions); - return as<VectorExpressionType>(DeclRefType::Create( + return DeclRefType::Create( session, - declRef)); + declRef).as<VectorExpressionType>(); } RefPtr<Expr> visitIndexExpr(IndexExpr* subscriptExpr) @@ -6258,8 +6260,8 @@ namespace Slang if (c.decl != typeParam.getDecl()) continue; - auto cType = c.val.dynamicCast<Type>(); - SLANG_RELEASE_ASSERT(cType.Ptr()); + auto cType = as<Type>(c.val); + SLANG_RELEASE_ASSERT(cType); if (!type) { @@ -6297,8 +6299,8 @@ namespace Slang if (c.decl != valParam.getDecl()) continue; - auto cVal = c.val.dynamicCast<IntVal>(); - SLANG_RELEASE_ASSERT(cVal.Ptr()); + auto cVal = as<IntVal>(c.val); + SLANG_RELEASE_ASSERT(cVal); if (!val) { @@ -6306,7 +6308,7 @@ namespace Slang } else { - if(!val->EqualsVal(cVal.Ptr())) + if(!val->EqualsVal(cVal)) { // failure! return SubstitutionSet(); @@ -6781,7 +6783,7 @@ namespace Slang // We should have the existing arguments to the generic // handy, so that we can construct a substitution list. - RefPtr<GenericSubstitution> subst = candidate.subst.dynamicCast<GenericSubstitution>(); + RefPtr<GenericSubstitution> subst = candidate.subst.as<GenericSubstitution>(); SLANG_ASSERT(subst); subst->genericDecl = genericDeclRef.getDecl(); @@ -6851,7 +6853,7 @@ namespace Slang RefPtr<Expr> originalExpr, RefPtr<GenericSubstitution> subst) { - auto baseDeclRefExpr = baseExpr.dynamicCast<DeclRefExpr>(); + auto baseDeclRefExpr = as<DeclRefExpr>(baseExpr); if (!baseDeclRefExpr) { SLANG_DIAGNOSE_UNEXPECTED(getSink(), baseExpr, "expected a reference to a generic declaration"); @@ -6928,7 +6930,7 @@ namespace Slang { case OverloadCandidate::Flavor::Func: { - RefPtr<AppExprBase> callExpr = context.originalExpr.as<InvokeExpr>(); + RefPtr<AppExprBase> callExpr = as<InvokeExpr>(context.originalExpr); if(!callExpr) { callExpr = new InvokeExpr(); @@ -7209,18 +7211,18 @@ namespace Slang RefPtr<Val> snd) { // if both values are types, then unify types - if (auto fstType = dynamicCast<Type>(fst)) + if (auto fstType = as<Type>(fst)) { - if (auto sndType = dynamicCast<Type>(snd)) + if (auto sndType = as<Type>(snd)) { return TryUnifyTypes(constraints, fstType, sndType); } } // if both values are constant integers, then compare them - if (auto fstIntVal = dynamicCast<ConstantIntVal>(fst)) + if (auto fstIntVal = as<ConstantIntVal>(fst)) { - if (auto sndIntVal = dynamicCast<ConstantIntVal>(snd)) + if (auto sndIntVal = as<ConstantIntVal>(snd)) { return fstIntVal->value == sndIntVal->value; } @@ -7735,7 +7737,7 @@ namespace Slang // for (auto genericDeclRef : getMembersOfType<GenericDecl>(aggTypeDeclRef)) { - if (auto ctorDecl = genericDeclRef.getDecl()->inner.as<ConstructorDecl>()) + if (auto ctorDecl = as<ConstructorDecl>(genericDeclRef.getDecl()->inner)) { DeclRef<Decl> innerRef = SpecializeGenericForOverload(genericDeclRef, context); if (!innerRef) @@ -9742,16 +9744,16 @@ namespace Slang isLValue = false; // Variables declared with `let` are always immutable. - if(varDeclRef.as<LetDecl>()) + if(as<LetDecl>(varDeclRef.getDecl())) isLValue = false; // Generic value parameters are always immutable - if(varDeclRef.as<GenericValueParamDecl>()) + if(as<GenericValueParamDecl>(varDeclRef.getDecl())) isLValue = false; // Function parameters declared in the "modern" style // are immutable unless they have an `out` or `inout` modifier. - if( varDeclRef.as<ModernParamDecl>() ) + if(as<ModernParamDecl>(varDeclRef.getDecl()) ) { // Note: the `inout` modifier AST class inherits from // the class for the `out` modifier so that we can diff --git a/source/slang/compiler.h b/source/slang/compiler.h index 9ca4bbc70..9e8f146b9 100644 --- a/source/slang/compiler.h +++ b/source/slang/compiler.h @@ -608,6 +608,9 @@ namespace Slang RefPtr<Type> constExprRate; RefPtr<Type> irBasicBlockType; + RefPtr<Type> stringType; + RefPtr<Type> enumTypeType; + ComPtr<ISlangSharedLibraryLoader> sharedLibraryLoader; ///< The shared library loader (never null) ComPtr<ISlangSharedLibrary> sharedLibraries[int(SharedLibraryType::CountOf)]; ///< The loaded shared libraries SlangFuncPtr sharedLibraryFunctions[int(SharedLibraryFuncType::CountOf)]; diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 224fa3a28..3be6c59cd 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -4238,11 +4238,11 @@ struct EmitVisitor if(auto layoutDecoration = inst->findDecoration<IRLayoutDecoration>()) { auto layout = layoutDecoration->getLayout(); - if(auto varLayout = dynamicCast<VarLayout>(layout)) + if(auto varLayout = as<VarLayout>(layout)) { emitIRSemantics(ctx, varLayout); } - else if (auto entryPointLayout = dynamicCast<EntryPointLayout>(layout)) + else if (auto entryPointLayout = as<EntryPointLayout>(layout)) { if(auto resultLayout = entryPointLayout->resultLayout) { @@ -5159,7 +5159,7 @@ struct EmitVisitor { if( auto layoutDecoration = func->findDecoration<IRLayoutDecoration>() ) { - return dynamicCast<EntryPointLayout>(layoutDecoration->getLayout()); + return as<EntryPointLayout>(layoutDecoration->getLayout()); } return nullptr; } @@ -5168,7 +5168,7 @@ struct EmitVisitor { if (auto layoutDecoration = func->findDecoration<IRLayoutDecoration>()) { - if (auto entryPointLayout = dynamicCast<EntryPointLayout>(layoutDecoration->getLayout())) + if (auto entryPointLayout = as<EntryPointLayout>(layoutDecoration->getLayout())) { return entryPointLayout; } diff --git a/source/slang/ir-entry-point-uniforms.cpp b/source/slang/ir-entry-point-uniforms.cpp index 64deec1c5..56a0defcf 100644 --- a/source/slang/ir-entry-point-uniforms.cpp +++ b/source/slang/ir-entry-point-uniforms.cpp @@ -162,7 +162,7 @@ struct MoveEntryPointUniformParametersToGlobalScope // an explicit IR constant buffer for that wrapper, // auto entryPointParamsLayout = entryPointLayout->parametersLayout; - bool needConstantBuffer = entryPointParamsLayout->typeLayout.as<ParameterGroupTypeLayout>() != nullptr; + bool needConstantBuffer = entryPointParamsLayout->typeLayout.is<ParameterGroupTypeLayout>(); // We will set up an IR builder so that we are ready to generate code. // diff --git a/source/slang/ir-legalize-types.cpp b/source/slang/ir-legalize-types.cpp index eb22da967..f73ef06a3 100644 --- a/source/slang/ir-legalize-types.cpp +++ b/source/slang/ir-legalize-types.cpp @@ -1017,7 +1017,7 @@ static LegalVal legalizeInst( RefPtr<VarLayout> findVarLayout(IRInst* value) { if (auto layoutDecoration = value->findDecoration<IRLayoutDecoration>()) - return dynamicCast<VarLayout>(layoutDecoration->getLayout()); + return as<VarLayout>(layoutDecoration->getLayout()); return nullptr; } diff --git a/source/slang/legalize-types.h b/source/slang/legalize-types.h index d45642927..f28078010 100644 --- a/source/slang/legalize-types.h +++ b/source/slang/legalize-types.h @@ -90,7 +90,7 @@ struct LegalType RefPtr<ImplicitDerefType> getImplicitDeref() const { SLANG_ASSERT(flavor == Flavor::implicitDeref); - return obj.dynamicCast<ImplicitDerefType>(); + return obj.as<ImplicitDerefType>(); } static LegalType tuple( @@ -99,7 +99,7 @@ struct LegalType RefPtr<TuplePseudoType> getTuple() const { SLANG_ASSERT(flavor == Flavor::tuple); - return obj.dynamicCast<TuplePseudoType>(); + return obj.as<TuplePseudoType>(); } static LegalType pair( @@ -113,7 +113,7 @@ struct LegalType RefPtr<PairPseudoType> getPair() const { SLANG_ASSERT(flavor == Flavor::pair); - return obj.dynamicCast<PairPseudoType>(); + return obj.as<PairPseudoType>(); } }; diff --git a/source/slang/lookup.cpp b/source/slang/lookup.cpp index d9e63ff09..0ded328c7 100644 --- a/source/slang/lookup.cpp +++ b/source/slang/lookup.cpp @@ -404,8 +404,7 @@ void DoLocalLookupImpl( } // if we are looking inside an interface decl, try find in the interfaces it inherits from - bool isInterface = targetDeclRef.as<InterfaceDecl>() ? true : false; - if (isInterface) + if (targetDeclRef.is<InterfaceDecl>()) { if(!targetDeclRefType) { diff --git a/source/slang/mangle.cpp b/source/slang/mangle.cpp index b153cb8dd..1ccd32b07 100644 --- a/source/slang/mangle.cpp +++ b/source/slang/mangle.cpp @@ -264,9 +264,11 @@ namespace Slang // Special case: accessors need some way to distinguish themselves // so that a getter/setter/ref-er don't all compile to the same name. - if(declRef.as<GetterDecl>()) emitRaw(context, "Ag"); - if(declRef.as<SetterDecl>()) emitRaw(context, "As"); - if(declRef.as<RefAccessorDecl>()) emitRaw(context, "Ar"); + { + if (declRef.is<GetterDecl>()) emitRaw(context, "Ag"); + if (declRef.is<SetterDecl>()) emitRaw(context, "As"); + if (declRef.is<RefAccessorDecl>()) emitRaw(context, "Ar"); + } // Are we the "inner" declaration beneath a generic decl? if(parentGenericDeclRef && (parentGenericDeclRef.getDecl()->inner.Ptr() == declRef.getDecl())) @@ -294,15 +296,15 @@ namespace Slang UInt genericParameterCount = 0; for( auto mm : getMembers(parentGenericDeclRef) ) { - if(mm.as<GenericTypeParamDecl>()) + if(as<GenericTypeParamDecl>(mm)) { genericParameterCount++; } - else if(mm.as<GenericValueParamDecl>()) + else if(as<GenericValueParamDecl>(mm)) { genericParameterCount++; } - else if(mm.as<GenericTypeConstraintDecl>()) + else if(as<GenericTypeConstraintDecl>(mm)) { genericParameterCount++; } @@ -358,7 +360,7 @@ namespace Slang // Don't print result type for an initializer/constructor, // since it is implicit in the qualified name. - if (!callableDeclRef.as<ConstructorDecl>()) + if (!callableDeclRef.is<ConstructorDecl>()) { emitType(context, GetResultType(callableDeclRef)); } diff --git a/source/slang/parameter-binding.cpp b/source/slang/parameter-binding.cpp index 904ec3129..e722ccbb9 100644 --- a/source/slang/parameter-binding.cpp +++ b/source/slang/parameter-binding.cpp @@ -785,12 +785,12 @@ static bool validateSpecializationsMatch( for(;;) { // Skip any global generic substitutions. - if(auto leftGlobalGeneric = ll.as<GlobalGenericParamSubstitution>()) + if(auto leftGlobalGeneric = as<GlobalGenericParamSubstitution>(ll)) { ll = leftGlobalGeneric->outer; continue; } - if(auto rightGlobalGeneric = rr.as<GlobalGenericParamSubstitution>()) + if(auto rightGlobalGeneric = as<GlobalGenericParamSubstitution>(rr)) { rr = rightGlobalGeneric->outer; continue; @@ -806,7 +806,7 @@ static bool validateSpecializationsMatch( ll = ll->outer; rr = rr->outer; - if(auto leftGeneric = leftSubst.as<GenericSubstitution>()) + if(auto leftGeneric = as<GenericSubstitution>(leftSubst)) { if(auto rightGeneric = as<GenericSubstitution>(rightSubst)) { @@ -816,9 +816,9 @@ static bool validateSpecializationsMatch( } } } - else if(auto leftThisType = leftSubst.as<ThisTypeSubstitution>()) + else if(auto leftThisType = as<ThisTypeSubstitution>(leftSubst)) { - if(auto rightThisType = rightSubst.as<ThisTypeSubstitution>()) + if(auto rightThisType = as<ThisTypeSubstitution>(rightSubst)) { if(validateThisTypeSubstitutionsMatch(context, leftThisType, rightThisType, stack)) { @@ -2494,7 +2494,7 @@ static void collectEntryPointParameters( // for( auto taggedUnionType : entryPoint->taggedUnionTypes ) { - auto substType = taggedUnionType->Substitute(typeSubst).dynamicCast<Type>(); + auto substType = taggedUnionType->Substitute(typeSubst).as<Type>(); auto typeLayout = CreateTypeLayout(context->layoutContext, substType); entryPointLayout->taggedUnionTypeLayouts.Add(typeLayout); } @@ -2610,7 +2610,7 @@ static void collectEntryPointParameters( auto resultTypeLayout = processEntryPointVaryingParameterDecl( context, entryPointFuncDecl, - resultType->Substitute(typeSubst).dynamicCast<Type>(), + resultType->Substitute(typeSubst).as<Type>(), state, resultLayout); diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp index 4c96929d8..0c6419ae3 100644 --- a/source/slang/parser.cpp +++ b/source/slang/parser.cpp @@ -821,7 +821,7 @@ namespace Slang auto keywordToken = advanceToken(parser); RefPtr<RefObject> parsedObject = syntaxDecl->parseCallback(parser, syntaxDecl->parseUserData); - auto syntax = dynamicCast<T>(parsedObject); + auto syntax = as<T>(parsedObject); if (syntax) { @@ -2997,7 +2997,7 @@ namespace Slang // then we really want the modifiers to apply to the inner declaration. // RefPtr<Decl> declToModify = decl; - if(auto genericDecl = decl.as<GenericDecl>()) + if(auto genericDecl = as<GenericDecl>(decl)) declToModify = genericDecl->inner; AddModifiers(declToModify.Ptr(), modifiers.first); diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp index ce42cf10d..68e0ce9e5 100644 --- a/source/slang/reflection.cpp +++ b/source/slang/reflection.cpp @@ -265,16 +265,16 @@ SLANG_API SlangTypeKind spReflectionType_GetKind(SlangReflectionType* inType) } else if( auto declRefType = as<DeclRefType>(type) ) { - auto declRef = declRefType->declRef; - if( auto structDeclRef = declRef.as<StructDecl>() ) + const auto& declRef = declRefType->declRef; + if(declRef.is<StructDecl>() ) { return SLANG_TYPE_KIND_STRUCT; } - else if (auto genericParamType = declRef.as<GlobalGenericParamDecl>()) + else if (declRef.is<GlobalGenericParamDecl>()) { return SLANG_TYPE_KIND_GENERIC_TYPE_PARAMETER; } - else if (auto interfaceType = declRef.as<InterfaceDecl>()) + else if (declRef.is<InterfaceDecl>()) { return SLANG_TYPE_KIND_INTERFACE; } diff --git a/source/slang/syntax-base-defs.h b/source/slang/syntax-base-defs.h index 7f49bb607..93fe687fd 100644 --- a/source/slang/syntax-base-defs.h +++ b/source/slang/syntax-base-defs.h @@ -80,27 +80,22 @@ public: Session* getSession() { return this->session; } void setSession(Session* s) { this->session = s; } - bool Equals(Type * type); - bool Equals(RefPtr<Type> type); - - bool IsTextureOrSampler(); - bool IsTexture() { return as<TextureType>(this) != nullptr; } - bool IsSampler() { return as<SamplerStateType>(this) != nullptr; } - bool IsStruct(); - //bool IsClass(); - + bool Equals(Type* type); + Type* GetCanonicalType(); virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; virtual bool EqualsVal(Val* val) override; + + ~Type(); + protected: - virtual bool EqualsImpl(Type * type) = 0; + virtual bool EqualsImpl(Type* type) = 0; virtual RefPtr<Type> CreateCanonicalType() = 0; Type* canonicalType = nullptr; - RefPtr<Type> canonicalTypeRefPtr; - + Session* session = nullptr; ) END_SYNTAX_CLASS() diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index 2be1a79ed..38618c7d3 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -113,14 +113,19 @@ void Type::accept(IValVisitor* visitor, void* extra) // - bool Type::Equals(Type * type) + Type::~Type() { - return GetCanonicalType()->EqualsImpl(type->GetCanonicalType()); + // If the canonicalType !=nullptr AND it is not set to this (ie the canonicalType is another object) + // then it needs to be released because it's owned by this object. + if (canonicalType && canonicalType != this) + { + canonicalType->releaseReference(); + } } - bool Type::Equals(RefPtr<Type> type) + bool Type::Equals(Type * type) { - return Equals(type.Ptr()); + return GetCanonicalType()->EqualsImpl(type->GetCanonicalType()); } bool Type::EqualsVal(Val* val) @@ -145,40 +150,26 @@ void Type::accept(IValVisitor* visitor, void* extra) return canSubst; } - Type* Type::GetCanonicalType() { - SLANG_ASSERT(this); - Type* et = const_cast<Type*>(this); if (!et->canonicalType) { // TODO(tfoley): worry about thread safety here? auto canType = et->CreateCanonicalType(); et->canonicalType = canType; - if (dynamic_cast<Type*>(et->canonicalType) != this) - et->canonicalTypeRefPtr = canType; - else - canType.detach(); + + // TODO(js): That this detachs when canType == this is a little surprising. It would seem + // as if this would create a circular reference on the object, but in practice there are + // no leaks so appears correct. + // That the dtor only releases if != this, also makes it surprising. + canType.detach(); + SLANG_ASSERT(et->canonicalType); } return et->canonicalType; } - bool Type::IsTextureOrSampler() - { - return IsTexture() || IsSampler(); - } - - bool Type::IsStruct() - { - auto declRefType = as<DeclRefType>(this); - if (!declRefType) return false; - auto structDeclRef = declRefType->declRef.as<StructDecl>(); - if (!structDeclRef) return false; - return true; - } - void Session::initializeTypes() { errorType = new ErrorType(); @@ -258,17 +249,24 @@ void Type::accept(IValVisitor* visitor, void* extra) Type* Session::getStringType() { - auto stringTypeDecl = findMagicDecl(this, "StringType"); - return DeclRefType::Create(this, makeDeclRef<Decl>(stringTypeDecl)); + if (stringType == nullptr) + { + auto stringTypeDecl = findMagicDecl(this, "StringType"); + stringType = DeclRefType::Create(this, makeDeclRef<Decl>(stringTypeDecl)); + } + return stringType; } Type* Session::getEnumTypeType() { - auto enumTypeTypeDecl = findMagicDecl(this, "EnumTypeType"); - return DeclRefType::Create(this, makeDeclRef<Decl>(enumTypeTypeDecl)); + if (enumTypeType == nullptr) + { + auto enumTypeTypeDecl = findMagicDecl(this, "EnumTypeType"); + enumTypeType = DeclRefType::Create(this, makeDeclRef<Decl>(enumTypeTypeDecl)); + } + return enumTypeType; } - RefPtr<PtrType> Session::getPtrType( RefPtr<Type> valueType) { @@ -293,8 +291,7 @@ void Type::accept(IValVisitor* visitor, void* extra) RefPtr<PtrTypeBase> Session::getPtrType(RefPtr<Type> valueType, char const* ptrTypeName) { - auto genericDecl = findMagicDecl( - this, ptrTypeName).dynamicCast<GenericDecl>(); + auto genericDecl = findMagicDecl(this, ptrTypeName).dynamicCast<GenericDecl>(); return getPtrType(valueType, genericDecl); } @@ -346,8 +343,8 @@ void Type::accept(IValVisitor* visitor, void* extra) RefPtr<Val> ArrayExpressionType::SubstituteImpl(SubstitutionSet subst, int* ioDiff) { int diff = 0; - auto elementType = baseType->SubstituteImpl(subst, &diff).dynamicCast<Type>(); - auto arrlen = ArrayLength->SubstituteImpl(subst, &diff).dynamicCast<IntVal>(); + auto elementType = baseType->SubstituteImpl(subst, &diff).as<Type>(); + auto arrlen = ArrayLength->SubstituteImpl(subst, &diff).as<IntVal>(); SLANG_ASSERT(arrlen); if (diff) { @@ -428,7 +425,7 @@ void Type::accept(IValVisitor* visitor, void* extra) RefPtr<WitnessTable> RequirementWitness::getWitnessTable() { SLANG_ASSERT(getFlavor() == Flavor::witnessTable); - return m_obj.dynamicCast<WitnessTable>(); + return m_obj.as<WitnessTable>(); } @@ -537,7 +534,7 @@ void Type::accept(IValVisitor* visitor, void* extra) // search for a substitution that might apply to us for(auto s = subst.substitutions; s; s = s->outer) { - auto genericSubst = s.dynamicCast<GenericSubstitution>(); + auto genericSubst = s.as<GenericSubstitution>(); if(!genericSubst) continue; @@ -640,7 +637,7 @@ void Type::accept(IValVisitor* visitor, void* extra) static RefPtr<Type> ExtractGenericArgType(RefPtr<Val> val) { - auto type = val.dynamicCast<Type>(); + auto type = val.as<Type>(); SLANG_RELEASE_ASSERT(type.Ptr()); return type; } @@ -731,7 +728,7 @@ void Type::accept(IValVisitor* visitor, void* extra) // TODO: need to figure out how to unify this with the logic // in the generic case... - DeclRefType* DeclRefType::Create( + RefPtr<DeclRefType> DeclRefType::Create( Session* session, DeclRef<Decl> declRef) { @@ -886,13 +883,13 @@ void Type::accept(IValVisitor* visitor, void* extra) SLANG_UNEXPECTED("unhandled type"); } - auto type = classInfo.createInstance(); + RefPtr<RefObject> type = classInfo.createInstance(); if (!type) { SLANG_UNEXPECTED("constructor failure"); } - auto declRefType = dynamic_cast<DeclRefType*>(type); + auto declRefType = dynamicCast<DeclRefType>(type); if (!declRefType) { SLANG_UNEXPECTED("expected a declaration reference type"); @@ -1068,13 +1065,13 @@ void Type::accept(IValVisitor* visitor, void* extra) int diff = 0; // result type - RefPtr<Type> substResultType = resultType->SubstituteImpl(subst, &diff).dynamicCast<Type>(); + RefPtr<Type> substResultType = resultType->SubstituteImpl(subst, &diff).as<Type>(); // parameter types List<RefPtr<Type>> substParamTypes; for( auto pp : paramTypes ) { - substParamTypes.Add(pp->SubstituteImpl(subst, &diff).dynamicCast<Type>()); + substParamTypes.Add(pp->SubstituteImpl(subst, &diff).as<Type>()); } // early exit for no change... @@ -1224,17 +1221,17 @@ void Type::accept(IValVisitor* visitor, void* extra) Type* MatrixExpressionType::getElementType() { - return dynamicCast<Type>(findInnerMostGenericSubstitution(declRef.substitutions)->args[0]); + return as<Type>(findInnerMostGenericSubstitution(declRef.substitutions)->args[0]); } IntVal* MatrixExpressionType::getRowCount() { - return dynamicCast<IntVal>(findInnerMostGenericSubstitution(declRef.substitutions)->args[1]); + return as<IntVal>(findInnerMostGenericSubstitution(declRef.substitutions)->args[1]); } IntVal* MatrixExpressionType::getColumnCount() { - return dynamicCast<IntVal>(findInnerMostGenericSubstitution(declRef.substitutions)->args[2]); + return as<IntVal>(findInnerMostGenericSubstitution(declRef.substitutions)->args[2]); } RefPtr<Type> MatrixExpressionType::getRowType() @@ -1261,9 +1258,9 @@ void Type::accept(IValVisitor* visitor, void* extra) auto declRef = DeclRef<Decl>(vectorTypeDecl.Ptr(), substitutions); - return as<VectorExpressionType>(DeclRefType::Create( + return DeclRefType::Create( this, - declRef)); + declRef).as<VectorExpressionType>(); } @@ -1271,7 +1268,7 @@ void Type::accept(IValVisitor* visitor, void* extra) Type* PtrTypeBase::getValueType() { - return dynamicCast<Type>(findInnerMostGenericSubstitution(declRef.substitutions)->args[0]); + return as<Type>(findInnerMostGenericSubstitution(declRef.substitutions)->args[0]); } // GenericParamIntVal @@ -1438,7 +1435,7 @@ void Type::accept(IValVisitor* visitor, void* extra) if(substOuter != outer) diff++; - auto substActualType = actualType->SubstituteImpl(substSet, &diff).dynamicCast<Type>(); + auto substActualType = actualType->SubstituteImpl(substSet, &diff).as<Type>(); List<ConstraintArg> substConstraintArgs; for(auto constraintArg : constraintArgs) @@ -1497,7 +1494,7 @@ void Type::accept(IValVisitor* visitor, void* extra) // Otherwise we need to recurse on the type structure // and apply substitutions where it makes sense - return type->Substitute(substitutions).dynamicCast<Type>(); + return type->Substitute(substitutions).as<Type>(); } DeclRefBase DeclRefBase::Substitute(DeclRefBase declRef) const @@ -1686,7 +1683,7 @@ void Type::accept(IValVisitor* visitor, void* extra) { // The declaration is nested inside a generic. // Does it already have a specialization for that generic? - if(auto specGenericSubst = substsToSpecialize.as<GenericSubstitution>()) + if(auto specGenericSubst = as<GenericSubstitution>(substsToSpecialize)) { if(specGenericSubst->genericDecl == ancestorGenericDecl) { @@ -1720,7 +1717,7 @@ void Type::accept(IValVisitor* visitor, void* extra) // for(auto s = substsToApply; s; s = s->outer) { - auto appGenericSubst = s.as<GenericSubstitution>(); + auto appGenericSubst = as<GenericSubstitution>(s); if(!appGenericSubst) continue; @@ -1756,7 +1753,7 @@ void Type::accept(IValVisitor* visitor, void* extra) // The declaration is nested inside a generic. // Does it already have a specialization for that generic? - if(auto specThisTypeSubst = substsToSpecialize.as<ThisTypeSubstitution>()) + if(auto specThisTypeSubst = as<ThisTypeSubstitution>(substsToSpecialize)) { if(specThisTypeSubst->interfaceDecl == ancestorInterfaceDecl) { @@ -1891,6 +1888,10 @@ void Type::accept(IValVisitor* visitor, void* extra) DeclRefBase DeclRefBase::GetParent() const { + // Want access to the free function (the 'as' method by default gets priority) + // Can access as method with this->as because it removes any ambiguity. + using Slang::as; + auto parentDecl = decl->ParentDecl; if (!parentDecl) return DeclRefBase(); @@ -1905,7 +1906,7 @@ void Type::accept(IValVisitor* visitor, void* extra) // and there might be a this-type substitution in place. // A reference to the parent of the interface declaration // should not include that substitution. - if(auto thisTypeSubst = substToApply.as<ThisTypeSubstitution>()) + if(auto thisTypeSubst = as<ThisTypeSubstitution>(substToApply)) { if(thisTypeSubst->interfaceDecl == interfaceDecl) { @@ -1923,7 +1924,7 @@ void Type::accept(IValVisitor* visitor, void* extra) // A decl-ref to the parent generic should *not* include // those substitutions. // - if(auto genericSubst = substToApply.as<GenericSubstitution>()) + if(auto genericSubst = as<GenericSubstitution>(substToApply)) { if(genericSubst->genericDecl == parentGenericDecl) { @@ -1973,7 +1974,7 @@ void Type::accept(IValVisitor* visitor, void* extra) bool ConstantIntVal::EqualsVal(Val* val) { - if (auto intVal = dynamicCast<ConstantIntVal>(val)) + if (auto intVal = as<ConstantIntVal>(val)) return value == intVal->value; return false; } @@ -2045,12 +2046,12 @@ void Type::accept(IValVisitor* visitor, void* extra) Type* HLSLPatchType::getElementType() { - return dynamicCast<Type>(findInnerMostGenericSubstitution(declRef.substitutions)->args[0]); + return as<Type>(findInnerMostGenericSubstitution(declRef.substitutions)->args[0]); } IntVal* HLSLPatchType::getElementCount() { - return dynamicCast<IntVal>(findInnerMostGenericSubstitution(declRef.substitutions)->args[1]); + return as<IntVal>(findInnerMostGenericSubstitution(declRef.substitutions)->args[1]); } // Constructors for types @@ -2160,8 +2161,8 @@ void Type::accept(IValVisitor* visitor, void* extra) RefPtr<Val> TypeEqualityWitness::SubstituteImpl(SubstitutionSet subst, int * ioDiff) { RefPtr<TypeEqualityWitness> rs = new TypeEqualityWitness(); - rs->sub = sub->SubstituteImpl(subst, ioDiff).dynamicCast<Type>(); - rs->sup = sup->SubstituteImpl(subst, ioDiff).dynamicCast<Type>(); + rs->sub = sub->SubstituteImpl(subst, ioDiff).as<Type>(); + rs->sup = sup->SubstituteImpl(subst, ioDiff).as<Type>(); return rs; } @@ -2192,7 +2193,7 @@ void Type::accept(IValVisitor* visitor, void* extra) { for(RefPtr<Substitutions> s = substs; s; s = s->outer) { - auto thisTypeSubst = s.dynamicCast<ThisTypeSubstitution>(); + auto thisTypeSubst = as<ThisTypeSubstitution>(s); if(!thisTypeSubst) continue; @@ -2214,7 +2215,7 @@ void Type::accept(IValVisitor* visitor, void* extra) // search for a substitution that might apply to us for(auto s = subst.substitutions; s; s = s->outer) { - if(auto genericSubst = s.as<GenericSubstitution>()) + if(auto genericSubst = as<GenericSubstitution>(s)) { // the generic decl associated with the substitution list must be // the generic decl that declared this parameter @@ -2226,9 +2227,9 @@ void Type::accept(IValVisitor* visitor, void* extra) UInt index = 0; for (auto m : genericDecl->Members) { - if (auto constraintParam = m.dynamicCast<GenericTypeConstraintDecl>()) + if (auto constraintParam = as<GenericTypeConstraintDecl>(m)) { - if (constraintParam.Ptr() == declRef.getDecl()) + if (constraintParam == declRef.getDecl()) { found = true; break; @@ -2265,8 +2266,8 @@ void Type::accept(IValVisitor* visitor, void* extra) // Perform substitution on the constituent elements. int diff = 0; - auto substSub = sub->SubstituteImpl(subst, &diff).dynamicCast<Type>(); - auto substSup = sup->SubstituteImpl(subst, &diff).dynamicCast<Type>(); + auto substSub = sub->SubstituteImpl(subst, &diff).as<Type>(); + auto substSup = sup->SubstituteImpl(subst, &diff).as<Type>(); auto substDeclRef = declRef.SubstituteImpl(subst, &diff); if (!diff) return this; @@ -2360,9 +2361,9 @@ void Type::accept(IValVisitor* visitor, void* extra) { int diff = 0; - RefPtr<Type> substSub = sub->SubstituteImpl(subst, &diff).dynamicCast<Type>(); - RefPtr<Type> substSup = sup->SubstituteImpl(subst, &diff).dynamicCast<Type>(); - RefPtr<SubtypeWitness> substSubToMid = subToMid->SubstituteImpl(subst, &diff).dynamicCast<SubtypeWitness>(); + RefPtr<Type> substSub = sub->SubstituteImpl(subst, &diff).as<Type>(); + RefPtr<Type> substSup = sup->SubstituteImpl(subst, &diff).as<Type>(); + RefPtr<SubtypeWitness> substSubToMid = subToMid->SubstituteImpl(subst, &diff).as<SubtypeWitness>(); DeclRef<Decl> substMidToSup = midToSup.SubstituteImpl(subst, &diff); // If nothing changed, then we can bail out early. @@ -2496,7 +2497,7 @@ void Type::accept(IValVisitor* visitor, void* extra) bool ExtractExistentialSubtypeWitness::EqualsVal(Val* val) { - if( auto extractWitness = dynamicCast<ExtractExistentialSubtypeWitness>(val) ) + if( auto extractWitness = as<ExtractExistentialSubtypeWitness>(val) ) { return declRef.Equals(extractWitness->declRef); } @@ -2522,8 +2523,8 @@ void Type::accept(IValVisitor* visitor, void* extra) int diff = 0; auto substDeclRef = declRef.SubstituteImpl(subst, &diff); - auto substSub = sub->SubstituteImpl(subst, &diff).dynamicCast<Type>(); - auto substSup = sup->SubstituteImpl(subst, &diff).dynamicCast<Type>(); + auto substSub = sub->SubstituteImpl(subst, &diff).as<Type>(); + auto substSup = sup->SubstituteImpl(subst, &diff).as<Type>(); if(!diff) return this; @@ -2606,7 +2607,7 @@ void Type::accept(IValVisitor* visitor, void* extra) List<RefPtr<Type>> substCaseTypes; for( auto caseType : caseTypes ) { - substCaseTypes.Add(caseType->SubstituteImpl(subst, &diff).dynamicCast<Type>()); + substCaseTypes.Add(caseType->SubstituteImpl(subst, &diff).as<Type>()); } if(!diff) return this; @@ -2626,7 +2627,7 @@ void Type::accept(IValVisitor* visitor, void* extra) bool TaggedUnionSubtypeWitness::EqualsVal(Val* val) { - auto taggedUnionWitness = dynamicCast<TaggedUnionSubtypeWitness>(val); + auto taggedUnionWitness = as<TaggedUnionSubtypeWitness>(val); if(!taggedUnionWitness) return false; @@ -2672,8 +2673,8 @@ RefPtr<Val> TaggedUnionSubtypeWitness::SubstituteImpl(SubstitutionSet subst, int { int diff = 0; - auto substSub = sub->SubstituteImpl(subst, &diff).dynamicCast<Type>(); - auto substSup = sup->SubstituteImpl(subst, &diff).dynamicCast<Type>(); + auto substSub = sub->SubstituteImpl(subst, &diff).as<Type>(); + auto substSup = sup->SubstituteImpl(subst, &diff).as<Type>(); List<RefPtr<Val>> substCaseWitnesses; for( auto caseWitness : caseWitnesses ) diff --git a/source/slang/syntax.h b/source/slang/syntax.h index 076d62d71..e354fff05 100644 --- a/source/slang/syntax.h +++ b/source/slang/syntax.h @@ -420,6 +420,10 @@ namespace Slang bool Equals(SubstitutionSet substSet) const; int GetHashCode() const; }; + + template<typename T> + struct DeclRef; + // A reference to a declaration, which may include // substitutions for generic parameters. struct DeclRefBase @@ -461,6 +465,13 @@ namespace Slang // Apply substitutions to this declaration reference DeclRefBase SubstituteImpl(SubstitutionSet subst, int* ioDiff); + // Returns true if 'as' will return a valid cast + template <typename T> + bool is() const { return Slang::as<T>(decl) != nullptr; } + + // "dynamic cast" to a more specific declaration reference type + template<typename T> + DeclRef<T> as() const; // Check if this is an equivalent declaration reference to another bool Equals(DeclRefBase const& declRef) const; @@ -502,16 +513,6 @@ namespace Slang { } - // "dynamic cast" to a more specific declaration reference type - template<typename U> - DeclRef<U> as() const - { - DeclRef<U> result; - result.decl = Slang::as<U>(decl); - result.substitutions = substitutions; - return result; - } - T* getDecl() const { return (T*)decl; @@ -537,7 +538,7 @@ namespace Slang return DeclRefBase::Substitute(expr); } - // Apply substitutions to a type or ddeclaration + // Apply substitutions to a type or declaration template<typename U> DeclRef<U> Substitute(DeclRef<U> declRef) const { @@ -556,7 +557,15 @@ namespace Slang } }; - + template<typename T> + DeclRef<T> DeclRefBase::as() const + { + DeclRef<T> result; + result.decl = Slang::as<T>(decl); + result.substitutions = substitutions; + return result; + } + template<typename T> inline DeclRef<T> makeDeclRef(T* decl) { @@ -723,12 +732,12 @@ namespace Slang RefPtr<Decl>* Adjust(RefPtr<Decl>* ptr, RefPtr<Decl>* end) const { - while (ptr != end) + for (; ptr != end; ptr++) { - DeclRef<Decl> declRef(ptr->Ptr(), substitutions); - if (declRef.as<T>()) + if (as<T>(*ptr)) + { return ptr; - ptr++; + } } return end; } @@ -1062,7 +1071,7 @@ namespace Slang RefPtr<Val> getVal() { SLANG_ASSERT(getFlavor() == Flavor::val); - return m_obj.dynamicCast<Val>(); + return m_obj.as<Val>(); } RefPtr<WitnessTable> getWitnessTable(); @@ -1165,7 +1174,7 @@ namespace Slang inline int GetVectorSize(VectorExpressionType* vecType) { - auto constantVal = vecType->elementCount.dynamicCast<ConstantIntVal>(); + auto constantVal = as<ConstantIntVal>(vecType->elementCount); if (constantVal) return (int) constantVal->value; // TODO: what to do in this case? diff --git a/source/slang/type-defs.h b/source/slang/type-defs.h index 2318c6933..b7af1d975 100644 --- a/source/slang/type-defs.h +++ b/source/slang/type-defs.h @@ -50,7 +50,7 @@ RAW( virtual String ToString() override; virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; - static DeclRefType* Create( + static RefPtr<DeclRefType> Create( Session* session, DeclRef<Decl> declRef); |
