From e0389f5a1f32cb611e5a595a5974ee1d5c15f43d Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Thu, 15 Jun 2017 16:35:10 -0700 Subject: Replace `DeclRef` approach For context: a `DeclRef` is supposed to capture both a pointer to a particualr declaration, and also any information needed to specialize that declaration for a context (e.g., generic parameter substitutions). The existing approach had a hiearchy of specialized decl-ref types that mirrored the AST hierarchy, but that led to a lot of boilerplate where you had to recapitulate the exact same hierarchy. The new appraoch basically treats `DeclRef` as a sort of "smart pointer" in that it wraps a pointer to a `T` (the declaration), plus a side field for the specialization info, and then allows it to be cast as needed to other types (where the pointer cast would be allowed), while carrying along the side info. To enable this, all the things that used to be member functions of declaration-reference types are now free functions that take a `DeclRef` for some specific `T` as a parameter. --- source/slang/syntax.cpp | 55 +++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 32 deletions(-) (limited to 'source/slang/syntax.cpp') diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index 19f3939ce..d37f782f6 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -291,20 +291,11 @@ namespace Slang { auto declRefType = AsDeclRefType(); if (!declRefType) return false; - auto structDeclRef = declRefType->declRef.As(); + auto structDeclRef = declRefType->declRef.As(); if (!structDeclRef) return false; return true; } - bool ExpressionType::IsClass() - { - auto declRefType = AsDeclRefType(); - if (!declRefType) return false; - auto classDeclRef = declRefType->declRef.As(); - if (!classDeclRef) return false; - return true; - } - #if 0 RefPtr ExpressionType::Bool; RefPtr ExpressionType::UInt; @@ -405,7 +396,7 @@ namespace Slang // the case we especially care about is when this type references a declaration // of a generic parameter, since that is what we might be substituting... - if (auto genericTypeParamDecl = dynamic_cast(declRef.GetDecl())) + if (auto genericTypeParamDecl = dynamic_cast(declRef.getDecl())) { // search for a substitution that might apply to us for (auto s = subst; s; s = s->outer.Ptr()) @@ -443,7 +434,7 @@ namespace Slang int diff = 0; - DeclRef substDeclRef = declRef.SubstituteImpl(subst, &diff); + DeclRef substDeclRef = declRef.SubstituteImpl(subst, &diff); if (!diff) return this; @@ -471,15 +462,15 @@ namespace Slang // TODO: need to figure out how to unify this with the logic // in the generic case... - DeclRefType* DeclRefType::Create(DeclRef declRef) + DeclRefType* DeclRefType::Create(DeclRef declRef) { - if (auto builtinMod = declRef.GetDecl()->FindModifier()) + if (auto builtinMod = declRef.getDecl()->FindModifier()) { auto type = new BasicExpressionType(builtinMod->tag); type->declRef = declRef; return type; } - else if (auto magicMod = declRef.GetDecl()->FindModifier()) + else if (auto magicMod = declRef.getDecl()->FindModifier()) { Substitutions* subst = declRef.substitutions.Ptr(); @@ -679,7 +670,7 @@ namespace Slang ExpressionType* NamedExpressionType::CreateCanonicalType() { - return declRef.GetType()->GetCanonicalType(); + return GetType(declRef)->GetCanonicalType(); } int NamedExpressionType::GetHashCode() @@ -754,7 +745,7 @@ namespace Slang String GenericDeclRefType::ToString() { // TODO: what is appropriate here? - return ""; + return ">"; } bool GenericDeclRefType::EqualsImpl(ExpressionType * type) @@ -1034,13 +1025,13 @@ namespace Slang // the generic decl associated with the substitution list must be // the generic decl that declared this parameter auto genericDecl = s->genericDecl; - if (genericDecl != declRef.GetDecl()->ParentDecl) + if (genericDecl != declRef.getDecl()->ParentDecl) continue; int index = 0; for (auto m : genericDecl->Members) { - if (m.Ptr() == declRef.GetDecl()) + if (m.Ptr() == declRef.getDecl()) { // We've found it, so return the corresponding specialization argument (*ioDiff)++; @@ -1144,9 +1135,9 @@ namespace Slang } - // DeclRef + // DeclRefBase - RefPtr DeclRef::Substitute(RefPtr type) const + RefPtr DeclRefBase::Substitute(RefPtr type) const { // No substitutions? Easy. if (!substitutions) @@ -1158,7 +1149,7 @@ namespace Slang return type->Substitute(substitutions.Ptr()).As(); } - DeclRef DeclRef::Substitute(DeclRef declRef) const + DeclRefBase DeclRefBase::Substitute(DeclRefBase declRef) const { if(!substitutions) return declRef; @@ -1167,7 +1158,7 @@ namespace Slang return declRef.SubstituteImpl(substitutions.Ptr(), &diff); } - RefPtr DeclRef::Substitute(RefPtr expr) const + RefPtr DeclRefBase::Substitute(RefPtr expr) const { // No substitutions? Easy. if (!substitutions) @@ -1179,7 +1170,7 @@ namespace Slang } - DeclRef DeclRef::SubstituteImpl(Substitutions* subst, int* ioDiff) + DeclRefBase DeclRefBase::SubstituteImpl(Substitutions* subst, int* ioDiff) { if (!substitutions) return *this; @@ -1191,7 +1182,7 @@ namespace Slang *ioDiff += diff; - DeclRef substDeclRef; + DeclRefBase substDeclRef; substDeclRef.decl = decl; substDeclRef.substitutions = substSubst; return substDeclRef; @@ -1199,7 +1190,7 @@ namespace Slang // Check if this is an equivalent declaration reference to another - bool DeclRef::Equals(DeclRef const& declRef) const + bool DeclRefBase::Equals(DeclRefBase const& declRef) const { if (decl != declRef.decl) return false; @@ -1211,30 +1202,30 @@ namespace Slang } // Convenience accessors for common properties of declarations - String const& DeclRef::GetName() const + String const& DeclRefBase::GetName() const { return decl->Name.Content; } - DeclRef DeclRef::GetParent() const + DeclRefBase DeclRefBase::GetParent() const { auto parentDecl = decl->ParentDecl; if (auto parentGeneric = dynamic_cast(parentDecl)) { // We need to strip away one layer of specialization assert(substitutions); - return DeclRef(parentGeneric, substitutions->outer); + return DeclRefBase(parentGeneric, substitutions->outer); } else { // If the parent isn't a generic, then it must // use the same specializations as this declaration - return DeclRef(parentDecl, substitutions); + return DeclRefBase(parentDecl, substitutions); } } - int DeclRef::GetHashCode() const + int DeclRefBase::GetHashCode() const { auto rs = PointerHash<1>::GetHashCode(decl); if (substitutions) @@ -1365,7 +1356,7 @@ namespace Slang RefPtr decl, RefPtr modifier) { - auto type = DeclRefType::Create(DeclRef(decl.Ptr(), nullptr)); + auto type = DeclRefType::Create(DeclRef(decl.Ptr(), nullptr)); ExpressionType::sBuiltinTypes[(int)modifier->tag] = type; } -- cgit v1.2.3