xref: /llvm-project/clang/include/clang/Sema/SemaHLSL.h (revision 951a284fdff43f9b3aa2d2dbb2d01bbce3ab0673)
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