From 3726194fbe3da234eb30b6371e5b4ab1ea388f93 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Sat, 2 Feb 2019 11:58:54 -0500 Subject: 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. --- source/core/smart-pointer.h | 3 + source/slang/check.cpp | 112 +++++++++++----------- source/slang/compiler.h | 3 + source/slang/emit.cpp | 8 +- source/slang/ir-entry-point-uniforms.cpp | 2 +- source/slang/ir-legalize-types.cpp | 2 +- source/slang/legalize-types.h | 6 +- source/slang/lookup.cpp | 3 +- source/slang/mangle.cpp | 16 ++-- source/slang/parameter-binding.cpp | 14 +-- source/slang/parser.cpp | 4 +- source/slang/reflection.cpp | 8 +- source/slang/syntax-base-defs.h | 19 ++-- source/slang/syntax.cpp | 153 ++++++++++++++++--------------- source/slang/syntax.h | 45 +++++---- source/slang/type-defs.h | 2 +- 16 files changed, 207 insertions(+), 193 deletions(-) (limited to 'source') 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(Slang::as(pointer)); } + template + bool is() const { return Slang::as(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(typeIn)) { - if (auto elemCount = vectorType->elementCount.dynamicCast()) + if (auto elemCount = as(vectorType->elementCount)) { data.dim1 = elemCount->value - 1; auto elementBasicType = as(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(); + auto thisTypeSubst = interfaceDeclRef.substitutions.substitutions.as(); if(thisTypeSubst && thisTypeSubst->interfaceDecl == interfaceDeclRef.decl) { // This isn't really an existential type, because somebody @@ -885,16 +885,16 @@ namespace Slang RefPtr ExpectATypeRepr(RefPtr expr) { - if (auto overloadedExpr = expr.dynamicCast()) + if (auto overloadedExpr = as(expr)) { expr = ResolveOverloadedExpr(overloadedExpr, LookupMask::type); } - if (auto typeType = as(expr->type.type)) + if (auto typeType = as(expr->type)) { return expr; } - else if (auto errorType = as(expr->type.type)) + else if (auto errorType = as(expr->type)) { return expr; } @@ -925,7 +925,7 @@ namespace Slang RefPtr ExtractGenericArgVal(RefPtr exp) { - if (auto overloadedExpr = exp.dynamicCast()) + if (auto overloadedExpr = as(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()) + if (auto varDecl = as(decl)) { if (auto parenScope = as(varDecl->ParentDecl)) { @@ -1076,7 +1076,7 @@ namespace Slang void EnusreAllDeclsRec(RefPtr decl) { checkDecl(decl); - if (auto containerDecl = decl.dynamicCast()) + if (auto containerDecl = as(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()) + if(auto typeType = as(typeExp.exp->type)) { type = typeType->type; } @@ -1141,7 +1141,7 @@ namespace Slang List> args; for (RefPtr member : genericDeclRef.getDecl()->Members) { - if (auto typeParam = member.dynamicCast()) + if (auto typeParam = as(member)) { if (!typeParam->initType.exp) { @@ -1157,7 +1157,7 @@ namespace Slang if (outProperType) args.Add(typeParam->initType.exp); } - else if (auto valParam = member.dynamicCast()) + else if (auto valParam = as(member)) { if (!valParam->initExpr) { @@ -1274,11 +1274,11 @@ namespace Slang // Capture the "base" expression in case this is a member reference RefPtr GetBaseExpr(RefPtr expr) { - if (auto memberExpr = expr.dynamicCast()) + if (auto memberExpr = as(expr)) { return memberExpr->BaseExpression; } - else if(auto overloadedExpr = expr.dynamicCast()) + else if(auto overloadedExpr = as(expr)) { return overloadedExpr->base; } @@ -1293,17 +1293,17 @@ namespace Slang { if(left == right) return true; - if(auto leftConst = left.dynamicCast()) + if(auto leftConst = as(left)) { - if(auto rightConst = right.dynamicCast()) + if(auto rightConst = as(right)) { return leftConst->value == rightConst->value; } } - if(auto leftVar = left.dynamicCast()) + if(auto leftVar = as(left)) { - if(auto rightVar = right.dynamicCast()) + if(auto rightVar = as(right)) { return leftVar->declRef.Equals(rightVar->declRef); } @@ -1352,7 +1352,7 @@ namespace Slang if(auto declRefType = as(type)) { - if(declRefType->declRef.as()) + if(as(declRefType->declRef)) return false; } @@ -1366,7 +1366,7 @@ namespace Slang { // A nested initializer list should always be used directly. // - if(fromExpr.dynamicCast()) + if(as(fromExpr)) { return true; } @@ -1500,7 +1500,7 @@ namespace Slang auto toElementType = toVecType->elementType; UInt elementCount = 0; - if (auto constElementCount = toElementCount.dynamicCast()) + if (auto constElementCount = as(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()) + if (auto constElementCount = as(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()) + if( auto fromInitializerListExpr = as(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()) + if (auto sharedTypeExpr = as(typeExp.exp)) { if (auto declRefType = as(sharedTypeExpr->base)) { declRefType->declRef.substitutions = createDefaultSubstitutions(getSession(), declRefType->declRef.getDecl()); - if (auto typetype = typeExp.exp->type.type.dynamicCast()) + + if (auto typetype = as(typeExp.exp->type)) typetype->type = declRefType; } } @@ -2707,8 +2708,9 @@ namespace Slang return uncheckedAttr; } - RefPtr attrObj = attrDecl->syntaxClass.createInstance(); - auto attr = attrObj.dynamicCast(); + // Manage scope + RefPtr attrInstance = attrDecl->syntaxClass.createInstance(); + auto attr = attrInstance.as(); if(!attr) { SLANG_DIAGNOSE_UNEXPECTED(getSink(), attrDecl, "attribute class did not yield an attribute object"); @@ -2802,7 +2804,7 @@ namespace Slang RefPtr m, ModifiableSyntaxNode* syntaxNode) { - if(auto hlslUncheckedAttribute = m.dynamicCast()) + if(auto hlslUncheckedAttribute = as(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()) + if (auto genTypeMbr = as(genMbr)) { - if (auto requiredGenTypeMbr = requiredGenMbr.dynamicCast()) + if (auto requiredGenTypeMbr = as(requiredGenMbr)) { } else return false; } - else if (auto genValMbr = genMbr.dynamicCast()) + else if (auto genValMbr = as(genMbr)) { - if (auto requiredGenValMbr = requiredGenMbr.dynamicCast()) + if (auto requiredGenValMbr = as(requiredGenMbr)) { if (!genValMbr->type->Equals(requiredGenValMbr->type)) return false; @@ -3054,9 +3056,9 @@ namespace Slang else return false; } - else if (auto genTypeConstraintMbr = genMbr.dynamicCast()) + else if (auto genTypeConstraintMbr = as(genMbr)) { - if (auto requiredTypeConstraintMbr = requiredGenMbr.dynamicCast()) + if (auto requiredTypeConstraintMbr = as(requiredGenMbr)) { if (!genTypeConstraintMbr->sup->Equals(requiredTypeConstraintMbr->sup)) { @@ -3844,7 +3846,7 @@ namespace Slang RefPtr explicitTagVal = TryConstantFoldExpr(explicitTagValExpr); if(explicitTagVal) { - if(auto constIntVal = explicitTagVal.dynamicCast()) + if(auto constIntVal = as(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(); + auto funcDeclRefExpr = invokeExpr->FunctionExpr.as(); if (!funcDeclRefExpr) return nullptr; auto funcDeclRef = funcDeclRefExpr->declRef; @@ -5197,7 +5199,7 @@ namespace Slang { auto session = getSession(); auto vectorGenericDecl = findMagicDecl( - session, "Vector").dynamicCast(); + session, "Vector").as(); auto vectorTypeDecl = vectorGenericDecl->inner; auto substitutions = new GenericSubstitution(); @@ -5207,9 +5209,9 @@ namespace Slang auto declRef = DeclRef(vectorTypeDecl.Ptr(), substitutions); - return as(DeclRefType::Create( + return DeclRefType::Create( session, - declRef)); + declRef).as(); } RefPtr visitIndexExpr(IndexExpr* subscriptExpr) @@ -6258,8 +6260,8 @@ namespace Slang if (c.decl != typeParam.getDecl()) continue; - auto cType = c.val.dynamicCast(); - SLANG_RELEASE_ASSERT(cType.Ptr()); + auto cType = as(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(); - SLANG_RELEASE_ASSERT(cVal.Ptr()); + auto cVal = as(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 subst = candidate.subst.dynamicCast(); + RefPtr subst = candidate.subst.as(); SLANG_ASSERT(subst); subst->genericDecl = genericDeclRef.getDecl(); @@ -6851,7 +6853,7 @@ namespace Slang RefPtr originalExpr, RefPtr subst) { - auto baseDeclRefExpr = baseExpr.dynamicCast(); + auto baseDeclRefExpr = as(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 callExpr = context.originalExpr.as(); + RefPtr callExpr = as(context.originalExpr); if(!callExpr) { callExpr = new InvokeExpr(); @@ -7209,18 +7211,18 @@ namespace Slang RefPtr snd) { // if both values are types, then unify types - if (auto fstType = dynamicCast(fst)) + if (auto fstType = as(fst)) { - if (auto sndType = dynamicCast(snd)) + if (auto sndType = as(snd)) { return TryUnifyTypes(constraints, fstType, sndType); } } // if both values are constant integers, then compare them - if (auto fstIntVal = dynamicCast(fst)) + if (auto fstIntVal = as(fst)) { - if (auto sndIntVal = dynamicCast(snd)) + if (auto sndIntVal = as(snd)) { return fstIntVal->value == sndIntVal->value; } @@ -7735,7 +7737,7 @@ namespace Slang // for (auto genericDeclRef : getMembersOfType(aggTypeDeclRef)) { - if (auto ctorDecl = genericDeclRef.getDecl()->inner.as()) + if (auto ctorDecl = as(genericDeclRef.getDecl()->inner)) { DeclRef innerRef = SpecializeGenericForOverload(genericDeclRef, context); if (!innerRef) @@ -9742,16 +9744,16 @@ namespace Slang isLValue = false; // Variables declared with `let` are always immutable. - if(varDeclRef.as()) + if(as(varDeclRef.getDecl())) isLValue = false; // Generic value parameters are always immutable - if(varDeclRef.as()) + if(as(varDeclRef.getDecl())) isLValue = false; // Function parameters declared in the "modern" style // are immutable unless they have an `out` or `inout` modifier. - if( varDeclRef.as() ) + if(as(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 constExprRate; RefPtr irBasicBlockType; + RefPtr stringType; + RefPtr enumTypeType; + ComPtr sharedLibraryLoader; ///< The shared library loader (never null) ComPtr 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()) { auto layout = layoutDecoration->getLayout(); - if(auto varLayout = dynamicCast(layout)) + if(auto varLayout = as(layout)) { emitIRSemantics(ctx, varLayout); } - else if (auto entryPointLayout = dynamicCast(layout)) + else if (auto entryPointLayout = as(layout)) { if(auto resultLayout = entryPointLayout->resultLayout) { @@ -5159,7 +5159,7 @@ struct EmitVisitor { if( auto layoutDecoration = func->findDecoration() ) { - return dynamicCast(layoutDecoration->getLayout()); + return as(layoutDecoration->getLayout()); } return nullptr; } @@ -5168,7 +5168,7 @@ struct EmitVisitor { if (auto layoutDecoration = func->findDecoration()) { - if (auto entryPointLayout = dynamicCast(layoutDecoration->getLayout())) + if (auto entryPointLayout = as(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() != nullptr; + bool needConstantBuffer = entryPointParamsLayout->typeLayout.is(); // 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 findVarLayout(IRInst* value) { if (auto layoutDecoration = value->findDecoration()) - return dynamicCast(layoutDecoration->getLayout()); + return as(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 getImplicitDeref() const { SLANG_ASSERT(flavor == Flavor::implicitDeref); - return obj.dynamicCast(); + return obj.as(); } static LegalType tuple( @@ -99,7 +99,7 @@ struct LegalType RefPtr getTuple() const { SLANG_ASSERT(flavor == Flavor::tuple); - return obj.dynamicCast(); + return obj.as(); } static LegalType pair( @@ -113,7 +113,7 @@ struct LegalType RefPtr getPair() const { SLANG_ASSERT(flavor == Flavor::pair); - return obj.dynamicCast(); + return obj.as(); } }; 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() ? true : false; - if (isInterface) + if (targetDeclRef.is()) { 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()) emitRaw(context, "Ag"); - if(declRef.as()) emitRaw(context, "As"); - if(declRef.as()) emitRaw(context, "Ar"); + { + if (declRef.is()) emitRaw(context, "Ag"); + if (declRef.is()) emitRaw(context, "As"); + if (declRef.is()) 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()) + if(as(mm)) { genericParameterCount++; } - else if(mm.as()) + else if(as(mm)) { genericParameterCount++; } - else if(mm.as()) + else if(as(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()) + if (!callableDeclRef.is()) { 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()) + if(auto leftGlobalGeneric = as(ll)) { ll = leftGlobalGeneric->outer; continue; } - if(auto rightGlobalGeneric = rr.as()) + if(auto rightGlobalGeneric = as(rr)) { rr = rightGlobalGeneric->outer; continue; @@ -806,7 +806,7 @@ static bool validateSpecializationsMatch( ll = ll->outer; rr = rr->outer; - if(auto leftGeneric = leftSubst.as()) + if(auto leftGeneric = as(leftSubst)) { if(auto rightGeneric = as(rightSubst)) { @@ -816,9 +816,9 @@ static bool validateSpecializationsMatch( } } } - else if(auto leftThisType = leftSubst.as()) + else if(auto leftThisType = as(leftSubst)) { - if(auto rightThisType = rightSubst.as()) + if(auto rightThisType = as(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(); + auto substType = taggedUnionType->Substitute(typeSubst).as(); 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(), + resultType->Substitute(typeSubst).as(), 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 parsedObject = syntaxDecl->parseCallback(parser, syntaxDecl->parseUserData); - auto syntax = dynamicCast(parsedObject); + auto syntax = as(parsedObject); if (syntax) { @@ -2997,7 +2997,7 @@ namespace Slang // then we really want the modifiers to apply to the inner declaration. // RefPtr declToModify = decl; - if(auto genericDecl = decl.as()) + if(auto genericDecl = as(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(type) ) { - auto declRef = declRefType->declRef; - if( auto structDeclRef = declRef.as() ) + const auto& declRef = declRefType->declRef; + if(declRef.is() ) { return SLANG_TYPE_KIND_STRUCT; } - else if (auto genericParamType = declRef.as()) + else if (declRef.is()) { return SLANG_TYPE_KIND_GENERIC_TYPE_PARAMETER; } - else if (auto interfaceType = declRef.as()) + else if (declRef.is()) { 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); - - bool IsTextureOrSampler(); - bool IsTexture() { return as(this) != nullptr; } - bool IsSampler() { return as(this) != nullptr; } - bool IsStruct(); - //bool IsClass(); - + bool Equals(Type* type); + Type* GetCanonicalType(); virtual RefPtr 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 CreateCanonicalType() = 0; Type* canonicalType = nullptr; - RefPtr 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) + 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(this); if (!et->canonicalType) { // TODO(tfoley): worry about thread safety here? auto canType = et->CreateCanonicalType(); et->canonicalType = canType; - if (dynamic_cast(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(this); - if (!declRefType) return false; - auto structDeclRef = declRefType->declRef.as(); - 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(stringTypeDecl)); + if (stringType == nullptr) + { + auto stringTypeDecl = findMagicDecl(this, "StringType"); + stringType = DeclRefType::Create(this, makeDeclRef(stringTypeDecl)); + } + return stringType; } Type* Session::getEnumTypeType() { - auto enumTypeTypeDecl = findMagicDecl(this, "EnumTypeType"); - return DeclRefType::Create(this, makeDeclRef(enumTypeTypeDecl)); + if (enumTypeType == nullptr) + { + auto enumTypeTypeDecl = findMagicDecl(this, "EnumTypeType"); + enumTypeType = DeclRefType::Create(this, makeDeclRef(enumTypeTypeDecl)); + } + return enumTypeType; } - RefPtr Session::getPtrType( RefPtr valueType) { @@ -293,8 +291,7 @@ void Type::accept(IValVisitor* visitor, void* extra) RefPtr Session::getPtrType(RefPtr valueType, char const* ptrTypeName) { - auto genericDecl = findMagicDecl( - this, ptrTypeName).dynamicCast(); + auto genericDecl = findMagicDecl(this, ptrTypeName).dynamicCast(); return getPtrType(valueType, genericDecl); } @@ -346,8 +343,8 @@ void Type::accept(IValVisitor* visitor, void* extra) RefPtr ArrayExpressionType::SubstituteImpl(SubstitutionSet subst, int* ioDiff) { int diff = 0; - auto elementType = baseType->SubstituteImpl(subst, &diff).dynamicCast(); - auto arrlen = ArrayLength->SubstituteImpl(subst, &diff).dynamicCast(); + auto elementType = baseType->SubstituteImpl(subst, &diff).as(); + auto arrlen = ArrayLength->SubstituteImpl(subst, &diff).as(); SLANG_ASSERT(arrlen); if (diff) { @@ -428,7 +425,7 @@ void Type::accept(IValVisitor* visitor, void* extra) RefPtr RequirementWitness::getWitnessTable() { SLANG_ASSERT(getFlavor() == Flavor::witnessTable); - return m_obj.dynamicCast(); + return m_obj.as(); } @@ -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(); + auto genericSubst = s.as(); if(!genericSubst) continue; @@ -640,7 +637,7 @@ void Type::accept(IValVisitor* visitor, void* extra) static RefPtr ExtractGenericArgType(RefPtr val) { - auto type = val.dynamicCast(); + auto type = val.as(); 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::Create( Session* session, DeclRef declRef) { @@ -886,13 +883,13 @@ void Type::accept(IValVisitor* visitor, void* extra) SLANG_UNEXPECTED("unhandled type"); } - auto type = classInfo.createInstance(); + RefPtr type = classInfo.createInstance(); if (!type) { SLANG_UNEXPECTED("constructor failure"); } - auto declRefType = dynamic_cast(type); + auto declRefType = dynamicCast(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 substResultType = resultType->SubstituteImpl(subst, &diff).dynamicCast(); + RefPtr substResultType = resultType->SubstituteImpl(subst, &diff).as(); // parameter types List> substParamTypes; for( auto pp : paramTypes ) { - substParamTypes.Add(pp->SubstituteImpl(subst, &diff).dynamicCast()); + substParamTypes.Add(pp->SubstituteImpl(subst, &diff).as()); } // early exit for no change... @@ -1224,17 +1221,17 @@ void Type::accept(IValVisitor* visitor, void* extra) Type* MatrixExpressionType::getElementType() { - return dynamicCast(findInnerMostGenericSubstitution(declRef.substitutions)->args[0]); + return as(findInnerMostGenericSubstitution(declRef.substitutions)->args[0]); } IntVal* MatrixExpressionType::getRowCount() { - return dynamicCast(findInnerMostGenericSubstitution(declRef.substitutions)->args[1]); + return as(findInnerMostGenericSubstitution(declRef.substitutions)->args[1]); } IntVal* MatrixExpressionType::getColumnCount() { - return dynamicCast(findInnerMostGenericSubstitution(declRef.substitutions)->args[2]); + return as(findInnerMostGenericSubstitution(declRef.substitutions)->args[2]); } RefPtr MatrixExpressionType::getRowType() @@ -1261,9 +1258,9 @@ void Type::accept(IValVisitor* visitor, void* extra) auto declRef = DeclRef(vectorTypeDecl.Ptr(), substitutions); - return as(DeclRefType::Create( + return DeclRefType::Create( this, - declRef)); + declRef).as(); } @@ -1271,7 +1268,7 @@ void Type::accept(IValVisitor* visitor, void* extra) Type* PtrTypeBase::getValueType() { - return dynamicCast(findInnerMostGenericSubstitution(declRef.substitutions)->args[0]); + return as(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(); + auto substActualType = actualType->SubstituteImpl(substSet, &diff).as(); List 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(); + return type->Substitute(substitutions).as(); } 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()) + if(auto specGenericSubst = as(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(); + auto appGenericSubst = as(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()) + if(auto specThisTypeSubst = as(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()) + if(auto thisTypeSubst = as(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()) + if(auto genericSubst = as(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(val)) + if (auto intVal = as(val)) return value == intVal->value; return false; } @@ -2045,12 +2046,12 @@ void Type::accept(IValVisitor* visitor, void* extra) Type* HLSLPatchType::getElementType() { - return dynamicCast(findInnerMostGenericSubstitution(declRef.substitutions)->args[0]); + return as(findInnerMostGenericSubstitution(declRef.substitutions)->args[0]); } IntVal* HLSLPatchType::getElementCount() { - return dynamicCast(findInnerMostGenericSubstitution(declRef.substitutions)->args[1]); + return as(findInnerMostGenericSubstitution(declRef.substitutions)->args[1]); } // Constructors for types @@ -2160,8 +2161,8 @@ void Type::accept(IValVisitor* visitor, void* extra) RefPtr TypeEqualityWitness::SubstituteImpl(SubstitutionSet subst, int * ioDiff) { RefPtr rs = new TypeEqualityWitness(); - rs->sub = sub->SubstituteImpl(subst, ioDiff).dynamicCast(); - rs->sup = sup->SubstituteImpl(subst, ioDiff).dynamicCast(); + rs->sub = sub->SubstituteImpl(subst, ioDiff).as(); + rs->sup = sup->SubstituteImpl(subst, ioDiff).as(); return rs; } @@ -2192,7 +2193,7 @@ void Type::accept(IValVisitor* visitor, void* extra) { for(RefPtr s = substs; s; s = s->outer) { - auto thisTypeSubst = s.dynamicCast(); + auto thisTypeSubst = as(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()) + if(auto genericSubst = as(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()) + if (auto constraintParam = as(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(); - auto substSup = sup->SubstituteImpl(subst, &diff).dynamicCast(); + auto substSub = sub->SubstituteImpl(subst, &diff).as(); + auto substSup = sup->SubstituteImpl(subst, &diff).as(); 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 substSub = sub->SubstituteImpl(subst, &diff).dynamicCast(); - RefPtr substSup = sup->SubstituteImpl(subst, &diff).dynamicCast(); - RefPtr substSubToMid = subToMid->SubstituteImpl(subst, &diff).dynamicCast(); + RefPtr substSub = sub->SubstituteImpl(subst, &diff).as(); + RefPtr substSup = sup->SubstituteImpl(subst, &diff).as(); + RefPtr substSubToMid = subToMid->SubstituteImpl(subst, &diff).as(); DeclRef 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(val) ) + if( auto extractWitness = as(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(); - auto substSup = sup->SubstituteImpl(subst, &diff).dynamicCast(); + auto substSub = sub->SubstituteImpl(subst, &diff).as(); + auto substSup = sup->SubstituteImpl(subst, &diff).as(); if(!diff) return this; @@ -2606,7 +2607,7 @@ void Type::accept(IValVisitor* visitor, void* extra) List> substCaseTypes; for( auto caseType : caseTypes ) { - substCaseTypes.Add(caseType->SubstituteImpl(subst, &diff).dynamicCast()); + substCaseTypes.Add(caseType->SubstituteImpl(subst, &diff).as()); } if(!diff) return this; @@ -2626,7 +2627,7 @@ void Type::accept(IValVisitor* visitor, void* extra) bool TaggedUnionSubtypeWitness::EqualsVal(Val* val) { - auto taggedUnionWitness = dynamicCast(val); + auto taggedUnionWitness = as(val); if(!taggedUnionWitness) return false; @@ -2672,8 +2673,8 @@ RefPtr TaggedUnionSubtypeWitness::SubstituteImpl(SubstitutionSet subst, int { int diff = 0; - auto substSub = sub->SubstituteImpl(subst, &diff).dynamicCast(); - auto substSup = sup->SubstituteImpl(subst, &diff).dynamicCast(); + auto substSub = sub->SubstituteImpl(subst, &diff).as(); + auto substSup = sup->SubstituteImpl(subst, &diff).as(); List> 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 + 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 + bool is() const { return Slang::as(decl) != nullptr; } + + // "dynamic cast" to a more specific declaration reference type + template + DeclRef 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 - DeclRef as() const - { - DeclRef result; - result.decl = Slang::as(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 DeclRef Substitute(DeclRef declRef) const { @@ -556,7 +557,15 @@ namespace Slang } }; - + template + DeclRef DeclRefBase::as() const + { + DeclRef result; + result.decl = Slang::as(decl); + result.substitutions = substitutions; + return result; + } + template inline DeclRef makeDeclRef(T* decl) { @@ -723,12 +732,12 @@ namespace Slang RefPtr* Adjust(RefPtr* ptr, RefPtr* end) const { - while (ptr != end) + for (; ptr != end; ptr++) { - DeclRef declRef(ptr->Ptr(), substitutions); - if (declRef.as()) + if (as(*ptr)) + { return ptr; - ptr++; + } } return end; } @@ -1062,7 +1071,7 @@ namespace Slang RefPtr getVal() { SLANG_ASSERT(getFlavor() == Flavor::val); - return m_obj.dynamicCast(); + return m_obj.as(); } RefPtr getWitnessTable(); @@ -1165,7 +1174,7 @@ namespace Slang inline int GetVectorSize(VectorExpressionType* vecType) { - auto constantVal = vecType->elementCount.dynamicCast(); + auto constantVal = as(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 SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; - static DeclRefType* Create( + static RefPtr Create( Session* session, DeclRef declRef); -- cgit v1.2.3