#ifndef SLANG_SYNTAX_H #define SLANG_SYNTAX_H #include "slang-ast-builder.h" namespace Slang { inline Type* getSub(ASTBuilder* astBuilder, DeclRef const& declRef) { return declRef.substitute(astBuilder, declRef.getDecl()->sub.Ptr()); } inline Type* getSup(ASTBuilder* astBuilder, DeclRef const& declRef) { return declRef.substitute(astBuilder, declRef.getDecl()->getSup().type); } // `Val` inline bool areValsEqual(Val* left, Val* right) { if(!left || !right) return left == right; return left->equalsVal(right); } // inline BaseType getVectorBaseType(VectorExpressionType* vecType) { auto basicExprType = as(vecType->elementType); return basicExprType->baseType; } inline int getVectorSize(VectorExpressionType* vecType) { auto constantVal = as(vecType->elementCount); if (constantVal) return (int) constantVal->value; // TODO: what to do in this case? return 0; } // // Declarations // inline ExtensionDecl* getCandidateExtensions(DeclRef const& declRef) { return declRef.getDecl()->candidateExtensions; } inline FilteredMemberRefList getMembers(DeclRef const& declRef, MemberFilterStyle filterStyle = MemberFilterStyle::All) { return FilteredMemberRefList(declRef.getDecl()->members, declRef.substitutions, filterStyle); } template inline FilteredMemberRefList getMembersOfType( DeclRef const& declRef, MemberFilterStyle filterStyle = MemberFilterStyle::All) { return FilteredMemberRefList(declRef.getDecl()->members, declRef.substitutions, filterStyle); } template inline List> getMembersOfTypeWithExt(DeclRef const& declRef, MemberFilterStyle filterStyle = MemberFilterStyle::All) { List> rs; for (auto d : getMembersOfType(declRef, filterStyle)) rs.add(d); if (auto aggDeclRef = declRef.as()) { for (auto ext = getCandidateExtensions(aggDeclRef); ext; ext = ext->nextCandidateExtension) { auto extMembers = getMembersOfType(DeclRef(ext, declRef.substitutions), filterStyle); for (auto mbr : extMembers) rs.add(mbr); } } return rs; } /// The the user-level name for a variable that might be a shader parameter. /// /// In most cases this is just the name of the variable declaration itself, /// but in the specific case of a `cbuffer`, the name that the user thinks /// of is really metadata. For example: /// /// cbuffer C { int x; } /// /// In this example, error messages relating to the constant buffer should /// really use the name `C`, but that isn't the name of the declaration /// (it is in practice anonymous, and `C` can be used for a different /// declaration in the same file). /// Name* getReflectionName(VarDeclBase* varDecl); inline Type* getType(ASTBuilder* astBuilder, DeclRef const& declRef) { return declRef.substitute(astBuilder, declRef.getDecl()->type.Ptr()); } inline Expr* getInitExpr(ASTBuilder* astBuilder, DeclRef const& declRef) { return declRef.substitute(astBuilder, declRef.getDecl()->initExpr); } inline Type* getType(ASTBuilder* astBuilder, DeclRef const& declRef) { return declRef.substitute(astBuilder, declRef.getDecl()->type.Ptr()); } inline Expr* getTagExpr(ASTBuilder* astBuilder, DeclRef const& declRef) { return declRef.substitute(astBuilder, declRef.getDecl()->tagExpr); } inline Type* getTargetType(ASTBuilder* astBuilder, DeclRef const& declRef) { return declRef.substitute(astBuilder, declRef.getDecl()->targetType.Ptr()); } inline FilteredMemberRefList getFields(DeclRef const& declRef, MemberFilterStyle filterStyle) { return getMembersOfType(declRef, filterStyle); } inline Type* getBaseType(ASTBuilder* astBuilder, DeclRef const& declRef) { return declRef.substitute(astBuilder, declRef.getDecl()->base.type); } inline Type* getType(ASTBuilder* astBuilder, DeclRef const& declRef) { return declRef.substitute(astBuilder, declRef.getDecl()->type.Ptr()); } inline Type* getResultType(ASTBuilder* astBuilder, DeclRef const& declRef) { return declRef.substitute(astBuilder, declRef.getDecl()->returnType.type); } inline FilteredMemberRefList getParameters(DeclRef const& declRef) { return getMembersOfType(declRef); } inline Decl* getInner(DeclRef const& declRef) { // TODO: Should really return a `DeclRef` for the inner // declaration, and not just a raw pointer return declRef.getDecl()->inner; } // ArrayExpressionType* getArrayType( ASTBuilder* astBuilder, Type* elementType, IntVal* elementCount); ArrayExpressionType* getArrayType( ASTBuilder* astBuilder, Type* elementType); NamedExpressionType* getNamedType( ASTBuilder* astBuilder, DeclRef const& declRef); FuncType* getFuncType( ASTBuilder* astBuilder, DeclRef const& declRef); GenericDeclRefType* getGenericDeclRefType( ASTBuilder* astBuilder, DeclRef const& declRef); NamespaceType* getNamespaceType( ASTBuilder* astBuilder, DeclRef const& declRef); SamplerStateType* getSamplerStateType( ASTBuilder* astBuilder); // Definitions that can't come earlier despite // being in templates, because gcc/clang get angry. // template void FilteredModifierList::Iterator::operator++() { current = adjust(current->next); } // template Modifier* FilteredModifierList::adjust(Modifier* modifier) { Modifier* m = modifier; for (;;) { if (!m) return m; if (as(m)) { return m; } m = m->next; } } // ThisTypeSubstitution* findThisTypeSubstitution( Substitutions* substs, InterfaceDecl* interfaceDecl); RequirementWitness tryLookUpRequirementWitness( ASTBuilder* astBuilder, SubtypeWitness* subtypeWitness, Decl* requirementKey); // TODO: where should this live? SubstitutionSet createDefaultSubstitutions( ASTBuilder* astBuilder, Decl* decl, SubstitutionSet parentSubst); SubstitutionSet createDefaultSubstitutions( ASTBuilder* astBuilder, Decl* decl); DeclRef createDefaultSubstitutionsIfNeeded( ASTBuilder* astBuilder, DeclRef declRef); GenericSubstitution* createDefaultSubstitutionsForGeneric( ASTBuilder* astBuilder, GenericDecl* genericDecl, Substitutions* outerSubst); GenericSubstitution* findInnerMostGenericSubstitution(Substitutions* subst); enum class UserDefinedAttributeTargets { None = 0, Struct = 1, Var = 2, Function = 4, All = 7 }; /// Get the module that a declaration is associated with, if any. Module* getModule(Decl* decl); } // namespace Slang #endif