1 //===----- SemaHLSL.h ----- Semantic Analysis for HLSL constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file declares semantic analysis for HLSL constructs. 10 /// 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_SEMA_SEMAHLSL_H 14 #define LLVM_CLANG_SEMA_SEMAHLSL_H 15 16 #include "clang/AST/ASTFwd.h" 17 #include "clang/AST/Attr.h" 18 #include "clang/AST/Type.h" 19 #include "clang/AST/TypeLoc.h" 20 #include "clang/Basic/SourceLocation.h" 21 #include "clang/Sema/SemaBase.h" 22 #include "llvm/ADT/SmallVector.h" 23 #include "llvm/TargetParser/Triple.h" 24 #include <initializer_list> 25 26 namespace clang { 27 class AttributeCommonInfo; 28 class IdentifierInfo; 29 class ParsedAttr; 30 class Scope; 31 class VarDecl; 32 33 using llvm::dxil::ResourceClass; 34 35 // FIXME: This can be hidden (as static function in SemaHLSL.cpp) once we no 36 // longer need to create builtin buffer types in HLSLExternalSemaSource. 37 bool CreateHLSLAttributedResourceType( 38 Sema &S, QualType Wrapped, ArrayRef<const Attr *> AttrList, 39 QualType &ResType, HLSLAttributedResourceLocInfo *LocInfo = nullptr); 40 41 enum class BindingType : uint8_t { NotAssigned, Explicit, Implicit }; 42 43 // DeclBindingInfo struct stores information about required/assigned resource 44 // binding onon a declaration for specific resource class. 45 struct DeclBindingInfo { 46 const VarDecl *Decl; 47 ResourceClass ResClass; 48 const HLSLResourceBindingAttr *Attr; 49 BindingType BindType; 50 51 DeclBindingInfo(const VarDecl *Decl, ResourceClass ResClass, 52 BindingType BindType = BindingType::NotAssigned, 53 const HLSLResourceBindingAttr *Attr = nullptr) 54 : Decl(Decl), ResClass(ResClass), Attr(Attr), BindType(BindType) {} 55 56 void setBindingAttribute(HLSLResourceBindingAttr *A, BindingType BT) { 57 assert(Attr == nullptr && BindType == BindingType::NotAssigned && 58 "binding attribute already assigned"); 59 Attr = A; 60 BindType = BT; 61 } 62 }; 63 64 // ResourceBindings class stores information about all resource bindings 65 // in a shader. It is used for binding diagnostics and implicit binding 66 // assigments. 67 class ResourceBindings { 68 public: 69 DeclBindingInfo *addDeclBindingInfo(const VarDecl *VD, 70 ResourceClass ResClass); 71 DeclBindingInfo *getDeclBindingInfo(const VarDecl *VD, 72 ResourceClass ResClass); 73 bool hasBindingInfoForDecl(const VarDecl *VD) const; 74 75 private: 76 // List of all resource bindings required by the shader. 77 // A global declaration can have multiple bindings for different 78 // resource classes. They are all stored sequentially in this list. 79 // The DeclToBindingListIndex hashtable maps a declaration to the 80 // index of the first binding info in the list. 81 llvm::SmallVector<DeclBindingInfo> BindingsList; 82 llvm::DenseMap<const VarDecl *, unsigned> DeclToBindingListIndex; 83 }; 84 85 class SemaHLSL : public SemaBase { 86 public: 87 SemaHLSL(Sema &S); 88 89 Decl *ActOnStartBuffer(Scope *BufferScope, bool CBuffer, SourceLocation KwLoc, 90 IdentifierInfo *Ident, SourceLocation IdentLoc, 91 SourceLocation LBrace); 92 void ActOnFinishBuffer(Decl *Dcl, SourceLocation RBrace); 93 HLSLNumThreadsAttr *mergeNumThreadsAttr(Decl *D, 94 const AttributeCommonInfo &AL, int X, 95 int Y, int Z); 96 HLSLWaveSizeAttr *mergeWaveSizeAttr(Decl *D, const AttributeCommonInfo &AL, 97 int Min, int Max, int Preferred, 98 int SpelledArgsCount); 99 HLSLShaderAttr *mergeShaderAttr(Decl *D, const AttributeCommonInfo &AL, 100 llvm::Triple::EnvironmentType ShaderType); 101 HLSLParamModifierAttr * 102 mergeParamModifierAttr(Decl *D, const AttributeCommonInfo &AL, 103 HLSLParamModifierAttr::Spelling Spelling); 104 void ActOnTopLevelFunction(FunctionDecl *FD); 105 void ActOnVariableDeclarator(VarDecl *VD); 106 void CheckEntryPoint(FunctionDecl *FD); 107 void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param, 108 const HLSLAnnotationAttr *AnnotationAttr); 109 void DiagnoseAttrStageMismatch( 110 const Attr *A, llvm::Triple::EnvironmentType Stage, 111 std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages); 112 void DiagnoseAvailabilityViolations(TranslationUnitDecl *TU); 113 114 QualType handleVectorBinOpConversion(ExprResult &LHS, ExprResult &RHS, 115 QualType LHSType, QualType RHSType, 116 bool IsCompAssign); 117 void emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, BinaryOperatorKind Opc); 118 119 void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL); 120 void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL); 121 void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL); 122 void handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL); 123 void handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL); 124 void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL); 125 void handleShaderAttr(Decl *D, const ParsedAttr &AL); 126 void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL); 127 void handleParamModifierAttr(Decl *D, const ParsedAttr &AL); 128 bool handleResourceTypeAttr(QualType T, const ParsedAttr &AL); 129 130 bool CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); 131 QualType ProcessResourceTypeAttributes(QualType Wrapped); 132 HLSLAttributedResourceLocInfo 133 TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT); 134 135 // HLSL Type trait implementations 136 bool IsScalarizedLayoutCompatible(QualType T1, QualType T2) const; 137 bool IsTypedResourceElementCompatible(QualType T1); 138 139 bool CheckCompatibleParameterABI(FunctionDecl *New, FunctionDecl *Old); 140 141 // Diagnose whether the input ID is uint/unit2/uint3 type. 142 bool diagnoseInputIDType(QualType T, const ParsedAttr &AL); 143 144 ExprResult ActOnOutParamExpr(ParmVarDecl *Param, Expr *Arg); 145 146 QualType getInoutParameterType(QualType Ty); 147 148 private: 149 // HLSL resource type attributes need to be processed all at once. 150 // This is a list to collect them. 151 llvm::SmallVector<const Attr *> HLSLResourcesTypeAttrs; 152 153 /// TypeLoc data for HLSLAttributedResourceType instances that we 154 /// have not yet populated. 155 llvm::DenseMap<const HLSLAttributedResourceType *, 156 HLSLAttributedResourceLocInfo> 157 LocsForHLSLAttributedResources; 158 159 // List of all resource bindings 160 ResourceBindings Bindings; 161 162 private: 163 void collectResourcesOnVarDecl(VarDecl *D); 164 void collectResourcesOnUserRecordDecl(const VarDecl *VD, 165 const RecordType *RT); 166 void processExplicitBindingsOnDecl(VarDecl *D); 167 }; 168 169 } // namespace clang 170 171 #endif // LLVM_CLANG_SEMA_SEMAHLSL_H 172