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.h | 338 +++++++++++++++++++++++--------------------------- 1 file changed, 153 insertions(+), 185 deletions(-) (limited to 'source/slang/syntax.h') diff --git a/source/slang/syntax.h b/source/slang/syntax.h index 96eb3d530..9f93c305c 100644 --- a/source/slang/syntax.h +++ b/source/slang/syntax.h @@ -700,73 +700,123 @@ namespace Slang // A reference to a declaration, which may include // substitutions for generic parameters. - struct DeclRef + struct DeclRefBase { typedef Decl DeclType; // The underlying declaration Decl* decl = nullptr; - Decl* GetDecl() const { return decl; } + Decl* getDecl() const { return decl; } // Optionally, a chain of substititions to perform RefPtr substitutions; - DeclRef() + DeclRefBase() {} - DeclRef(Decl* decl, RefPtr substitutions) + DeclRefBase(Decl* decl, RefPtr substitutions) : decl(decl) , substitutions(substitutions) {} // Apply substitutions to a type or ddeclaration RefPtr Substitute(RefPtr type) const; - DeclRef Substitute(DeclRef declRef) const; + + DeclRefBase Substitute(DeclRefBase declRef) const; // Apply substitutions to an expression RefPtr Substitute(RefPtr expr) const; // Apply substitutions to this declaration reference - DeclRef SubstituteImpl(Substitutions* subst, int* ioDiff); + DeclRefBase SubstituteImpl(Substitutions* subst, int* ioDiff); // Check if this is an equivalent declaration reference to another - bool Equals(DeclRef const& declRef) const; - bool operator == (const DeclRef& other) const + bool Equals(DeclRefBase const& declRef) const; + bool operator == (const DeclRefBase& other) const { return Equals(other); } // Convenience accessors for common properties of declarations String const& GetName() const; - DeclRef GetParent() const; + DeclRefBase GetParent() const; + + int GetHashCode() const; + }; + + template + struct DeclRef : DeclRefBase + { + typedef T DeclType; + + DeclRef() + {} + + DeclRef(T* decl, RefPtr substitutions) + : DeclRefBase(decl, substitutions) + {} + + template + DeclRef(DeclRef const& other, + typename EnableIf::Value, void>::type* = 0) + : DeclRefBase(other.decl, other.substitutions) + { + } // "dynamic cast" to a more specific declaration reference type template - T As() const + DeclRef As() const { - T result; - result.decl = dynamic_cast(decl); + DeclRef result; + result.decl = dynamic_cast(decl); result.substitutions = substitutions; return result; } - // Implicit conversion mostly so we can use a `DeclRef` - // in a conditional context - operator Decl*() const + T* getDecl() const { - return decl; + return (T*)decl; } - int GetHashCode() const; - }; + operator T*() const + { + return getDecl(); + } - // Helper macro for defining `DeclRef` subtypes - #define SLANG_DECLARE_DECL_REF(D) \ - typedef D DeclType; \ - D* GetDecl() const { return (D*) decl; } \ - /* */ + // + static DeclRef unsafeInit(DeclRefBase const& declRef) + { + return DeclRef((T*) declRef.decl, declRef.substitutions); + } + RefPtr Substitute(RefPtr type) const + { + return DeclRefBase::Substitute(type); + } + RefPtr Substitute(RefPtr expr) const + { + return DeclRefBase::Substitute(expr); + } + // Apply substitutions to a type or ddeclaration + template + DeclRef Substitute(DeclRef declRef) const + { + return DeclRef::unsafeInit(DeclRefBase::Substitute(declRef)); + } + + // Apply substitutions to this declaration reference + DeclRef SubstituteImpl(Substitutions* subst, int* ioDiff) + { + return DeclRef::unsafeInit(DeclRefBase::SubstituteImpl(subst, ioDiff)); + } + + DeclRef GetParent() const + { + return DeclRef::unsafeInit(DeclRefBase::GetParent()); + } + + }; // The type of a reference to an overloaded name class OverloadGroupType : public ExpressionType @@ -809,17 +859,17 @@ namespace Slang class DeclRefType : public ExpressionType { public: - DeclRef declRef; + DeclRef declRef; virtual String ToString() override; virtual RefPtr SubstituteImpl(Substitutions* subst, int* ioDiff) override; - static DeclRefType* Create(DeclRef declRef); + static DeclRefType* Create(DeclRef declRef); protected: DeclRefType() {} - DeclRefType(DeclRef declRef) + DeclRefType(DeclRef declRef) : declRef(declRef) {} virtual int GetHashCode() override; @@ -1246,7 +1296,7 @@ namespace Slang List> Members; template - FilteredMemberList GetMembersOfType() + FilteredMemberList getMembersOfType() { return FilteredMemberList(Members); } @@ -1286,9 +1336,9 @@ namespace Slang return count; } - List ToArray() const + List> ToArray() const { - List result; + List> result; for (auto d : *this) result.Add(d); return result; @@ -1320,9 +1370,9 @@ namespace Slang ptr = list->Adjust(ptr + 1, end); } - T operator*() + DeclRef operator*() { - return DeclRef(ptr->Ptr(), list->substitutions).As(); + return DeclRef((T*) ptr->Ptr(), list->substitutions); } }; @@ -1333,7 +1383,7 @@ namespace Slang { while (ptr != end) { - DeclRef declRef(ptr->Ptr(), substitutions); + DeclRef declRef(ptr->Ptr(), substitutions); if (declRef.As()) return ptr; ptr++; @@ -1342,22 +1392,16 @@ namespace Slang } }; - struct ContainerDeclRef : DeclRef + inline FilteredMemberRefList getMembers(DeclRef const& declRef) { - SLANG_DECLARE_DECL_REF(ContainerDecl); - - FilteredMemberRefList GetMembers() const - { - return FilteredMemberRefList(GetDecl()->Members, substitutions); - } - - template - FilteredMemberRefList GetMembersOfType() const - { - return FilteredMemberRefList(GetDecl()->Members, substitutions); - } + return FilteredMemberRefList(declRef.getDecl()->Members, declRef.substitutions); + } - }; + template + inline FilteredMemberRefList getMembersOfType(DeclRef const& declRef) + { + return FilteredMemberRefList(declRef.getDecl()->Members, declRef.substitutions); + } // // Type Expressions @@ -1417,14 +1461,15 @@ namespace Slang RefPtr Expr; }; - struct VarDeclBaseRef : DeclRef + inline RefPtr GetType(DeclRef const& declRef) { - SLANG_DECLARE_DECL_REF(VarDeclBase); - - RefPtr GetType() const { return Substitute(GetDecl()->Type); } + return declRef.Substitute(declRef.getDecl()->Type); + } - RefPtr getInitExpr() const { return Substitute(GetDecl()->Expr); } - }; + inline RefPtr getInitExpr(DeclRef const& declRef) + { + return declRef.Substitute(declRef.getDecl()->Expr); + } // A field of a `struct` type class StructField : public VarDeclBase @@ -1435,11 +1480,6 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct FieldDeclRef : VarDeclBaseRef - { - SLANG_DECLARE_DECL_REF(StructField) - }; - // An `AggTypeDeclBase` captures the shared functionality // between true aggregate type declarations and extension // declarations: @@ -1453,11 +1493,6 @@ namespace Slang public: }; - struct AggTypeDeclBaseRef : ContainerDeclRef - { - SLANG_DECLARE_DECL_REF(AggTypeDeclBase); - }; - // An extension to apply to an existing type class ExtensionDecl : public AggTypeDeclBase { @@ -1471,12 +1506,11 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct ExtensionDeclRef : AggTypeDeclBaseRef - { - SLANG_DECLARE_DECL_REF(ExtensionDecl); - RefPtr GetTargetType() const { return Substitute(GetDecl()->targetType); } - }; + inline RefPtr GetTargetType(DeclRef const& declRef) + { + return declRef.Substitute(declRef.getDecl()->targetType); + } // Declaration of a type that represents some sort of aggregate class AggTypeDecl : public AggTypeDeclBase @@ -1487,7 +1521,7 @@ namespace Slang ExtensionDecl* candidateExtensions = nullptr; FilteredMemberList GetFields() { - return GetMembersOfType(); + return getMembersOfType(); } StructField* FindField(String name) { @@ -1511,12 +1545,10 @@ namespace Slang } }; - struct AggTypeDeclRef : public AggTypeDeclBaseRef + inline ExtensionDecl* GetCandidateExtensions(DeclRef const& declRef) { - SLANG_DECLARE_DECL_REF(AggTypeDecl); - - ExtensionDecl* GetCandidateExtensions() const { return GetDecl()->candidateExtensions; } - }; + return declRef.getDecl()->candidateExtensions; + } class StructSyntaxNode : public AggTypeDecl { @@ -1524,12 +1556,10 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct StructDeclRef : public AggTypeDeclRef + inline FilteredMemberRefList GetFields(DeclRef const& declRef) { - SLANG_DECLARE_DECL_REF(StructSyntaxNode); - - FilteredMemberRefList GetFields() const { return GetMembersOfType(); } - }; + return getMembersOfType(declRef); + } class ClassSyntaxNode : public AggTypeDecl { @@ -1537,13 +1567,6 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct ClassDeclRef : public AggTypeDeclRef - { - SLANG_DECLARE_DECL_REF(ClassSyntaxNode); - - FilteredMemberRefList GetFields() const { return GetMembersOfType(); } - }; - // An interface which other types can conform to class InterfaceDecl : public AggTypeDecl { @@ -1551,12 +1574,6 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct InterfaceDeclRef : public AggTypeDeclRef - { - SLANG_DECLARE_DECL_REF(InterfaceDecl); - }; - - // A kind of pseudo-member that represents an explicit // or implicit inheritance relationship. // @@ -1569,12 +1586,10 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct InheritanceDeclRef : public DeclRef + inline RefPtr getBaseType(DeclRef const& declRef) { - SLANG_DECLARE_DECL_REF(InheritanceDecl); - - RefPtr getBaseType() { return Substitute(GetDecl()->base.type); } - }; + return declRef.Substitute(declRef.getDecl()->base.type); + } // TODO: may eventually need sub-classes for explicit/direct vs. implicit/indirect inheritance @@ -1584,11 +1599,6 @@ namespace Slang { }; - struct SimpleTypeDeclRef : DeclRef - { - SLANG_DECLARE_DECL_REF(SimpleTypeDecl) - }; - // A `typedef` declaration class TypeDefDecl : public SimpleTypeDecl { @@ -1598,22 +1608,20 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct TypeDefDeclRef : SimpleTypeDeclRef + inline RefPtr GetType(DeclRef const& declRef) { - SLANG_DECLARE_DECL_REF(TypeDefDecl); - - RefPtr GetType() const { return Substitute(GetDecl()->Type); } - }; + return declRef.Substitute(declRef.getDecl()->Type); + } // A type alias of some kind (e.g., via `typedef`) class NamedExpressionType : public ExpressionType { public: - NamedExpressionType(TypeDefDeclRef declRef) + NamedExpressionType(DeclRef declRef) : declRef(declRef) {} - TypeDefDeclRef declRef; + DeclRef declRef; virtual String ToString() override; @@ -1664,36 +1672,26 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct ParamDeclRef : VarDeclBaseRef - { - SLANG_DECLARE_DECL_REF(ParameterSyntaxNode); - }; - // Base class for things that have parameter lists and can thus be applied to arguments ("called") class CallableDecl : public ContainerDecl { public: FilteredMemberList GetParameters() { - return GetMembersOfType(); + return getMembersOfType(); } TypeExp ReturnType; }; - struct CallableDeclRef : ContainerDeclRef + inline RefPtr GetResultType(DeclRef const& declRef) { - SLANG_DECLARE_DECL_REF(CallableDecl); - - RefPtr GetResultType() const - { - return Substitute(GetDecl()->ReturnType.type.Ptr()); - } + return declRef.Substitute(declRef.getDecl()->ReturnType.type.Ptr()); + } - FilteredMemberRefList GetParameters() - { - return GetMembersOfType(); - } - }; + inline FilteredMemberRefList GetParameters(DeclRef const& declRef) + { + return getMembersOfType(declRef); + } // Base class for callable things that may also have a body that is evaluated to produce their result class FunctionDeclBase : public CallableDecl @@ -1702,11 +1700,6 @@ namespace Slang RefPtr Body; }; - struct FuncDeclBaseRef : CallableDeclRef - { - SLANG_DECLARE_DECL_REF(FunctionDeclBase); - }; - // Function types are currently used for references to symbols that name // either ordinary functions, or "component functions." // We do not directly store a representation of the type, and instead @@ -1714,7 +1707,7 @@ namespace Slang class FuncType : public ExpressionType { public: - CallableDeclRef declRef; + DeclRef declRef; virtual String ToString() override; protected: @@ -1730,11 +1723,6 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct ConstructorDeclRef : FuncDeclBaseRef - { - SLANG_DECLARE_DECL_REF(ConstructorDecl); - }; - // A subscript operation used to index instances of a type class SubscriptDecl : public CallableDecl { @@ -1742,11 +1730,6 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct SubscriptDeclRef : CallableDeclRef - { - SLANG_DECLARE_DECL_REF(SubscriptDecl); - }; - // An "accessor" for a subscript or property class AccessorDecl : public FunctionDeclBase { @@ -1776,12 +1759,6 @@ namespace Slang } }; - struct FuncDeclRef : FuncDeclBaseRef - { - SLANG_DECLARE_DECL_REF(FunctionSyntaxNode); - }; - - struct Scope : public RefObject { // The parent of this scope (where lookup should go if nothing is found locally) @@ -1806,7 +1783,7 @@ namespace Slang RefPtr scope; // The declaration of the symbol being referenced - DeclRef declRef; + DeclRef declRef; }; class VarExpressionSyntaxNode : public DeclRefExpr @@ -1848,10 +1825,10 @@ namespace Slang }; Kind kind; - DeclRef declRef; + DeclRef declRef; RefPtr next; - Breadcrumb(Kind kind, DeclRef declRef, RefPtr next) + Breadcrumb(Kind kind, DeclRef declRef, RefPtr next) : kind(kind) , declRef(declRef) , next(next) @@ -1859,7 +1836,7 @@ namespace Slang }; // A properly-specialized reference to the declaration that was found. - DeclRef declRef; + DeclRef declRef; // Any breadcrumbs needed in order to turn that declaration // reference into a well-formed expression. @@ -1870,10 +1847,10 @@ namespace Slang RefPtr breadcrumbs; LookupResultItem() = default; - explicit LookupResultItem(DeclRef declRef) + explicit LookupResultItem(DeclRef declRef) : declRef(declRef) {} - LookupResultItem(DeclRef declRef, RefPtr breadcrumbs) + LookupResultItem(DeclRef declRef, RefPtr breadcrumbs) : declRef(declRef) , breadcrumbs(breadcrumbs) {} @@ -1894,7 +1871,7 @@ namespace Slang List items; // Was at least one result found? - bool isValid() const { return item.declRef.GetDecl() != nullptr; } + bool isValid() const { return item.declRef.getDecl() != nullptr; } bool isOverloaded() const { return items.Count() > 1; } }; @@ -2076,20 +2053,20 @@ namespace Slang // Access members of specific types FilteredMemberList GetFunctions() { - return GetMembersOfType(); + return getMembersOfType(); } FilteredMemberList GetClasses() { - return GetMembersOfType(); + return getMembersOfType(); } FilteredMemberList GetStructs() { - return GetMembersOfType(); + return getMembersOfType(); } FilteredMemberList GetTypeDefs() { - return GetMembersOfType(); + return getMembersOfType(); } virtual RefPtr Accept(SyntaxVisitor * visitor) override; @@ -2372,23 +2349,23 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct GenericDeclRef : ContainerDeclRef + inline Decl* GetInner(DeclRef const& declRef) { - SLANG_DECLARE_DECL_REF(GenericDecl); - - Decl* GetInner() const { return GetDecl()->inner.Ptr(); } - }; + // TODO: Should really return a `DeclRef` for the inner + // declaration, and not just a raw pointer + return declRef.getDecl()->inner.Ptr(); + } // The "type" of an expression that names a generic declaration. class GenericDeclRefType : public ExpressionType { public: - GenericDeclRefType(GenericDeclRef declRef) + GenericDeclRefType(DeclRef declRef) : declRef(declRef) {} - GenericDeclRef declRef; - GenericDeclRef const& GetDeclRef() const { return declRef; } + DeclRef declRef; + DeclRef const& GetDeclRef() const { return declRef; } virtual String ToString() override; @@ -2413,11 +2390,6 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct GenericTypeParamDeclRef : SimpleTypeDeclRef - { - SLANG_DECLARE_DECL_REF(GenericTypeParamDecl); - }; - // A constraint placed as part of a generic declaration class GenericTypeConstraintDecl : public Decl { @@ -2432,14 +2404,15 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct GenericTypeConstraintDeclRef : DeclRef + inline RefPtr GetSub(DeclRef const& declRef) { - SLANG_DECLARE_DECL_REF(GenericTypeConstraintDecl); - - RefPtr GetSub() { return Substitute(GetDecl()->sub); } - RefPtr GetSup() { return Substitute(GetDecl()->sup); } - }; + return declRef.Substitute(declRef.getDecl()->sub); + } + inline RefPtr GetSup(DeclRef const& declRef) + { + return declRef.Substitute(declRef.getDecl()->sup); + } class GenericValueParamDecl : public VarDeclBase { @@ -2447,18 +2420,13 @@ namespace Slang virtual RefPtr Accept(SyntaxVisitor * visitor) override; }; - struct GenericValueParamDeclRef : VarDeclBaseRef - { - SLANG_DECLARE_DECL_REF(GenericValueParamDecl); - }; - // The logical "value" of a rererence to a generic value parameter class GenericParamIntVal : public IntVal { public: - VarDeclBaseRef declRef; + DeclRef declRef; - GenericParamIntVal(VarDeclBaseRef declRef) + GenericParamIntVal(DeclRef declRef) : declRef(declRef) {} -- cgit v1.2.3