clang 23.0.0git
HLSLResource.h
Go to the documentation of this file.
1//===- HLSLResource.h - Routines for HLSL resources and bindings ----------===//
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//
9// This file provides shared routines to help analyze HLSL resources and
10// theirs bindings during Sema and CodeGen.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_HLSLRESOURCE_H
15#define LLVM_CLANG_AST_HLSLRESOURCE_H
16
18#include "clang/AST/Attr.h"
19#include "clang/AST/DeclBase.h"
23#include "llvm/Frontend/HLSL/HLSLResource.h"
24#include "llvm/Support/raw_ostream.h"
25
26namespace clang {
27
28class HLSLResourceBindingAttr;
29class HLSLRVkBindingAttr;
30
31namespace hlsl {
32
34 HLSLResourceBindingAttr *RegBinding;
35 HLSLVkBindingAttr *VkBinding;
36
38 RegBinding = D->getAttr<HLSLResourceBindingAttr>();
39 bool IsSpirv = D->getASTContext().getTargetInfo().getTriple().isSPIRV();
40 VkBinding = IsSpirv ? D->getAttr<HLSLVkBindingAttr>() : nullptr;
41 }
42
43 bool hasBinding() const { return RegBinding || VkBinding; }
44 bool isExplicit() const {
45 return (RegBinding && RegBinding->hasRegisterSlot()) || VkBinding;
46 }
47
48 unsigned getSlot() const {
49 assert(isExplicit() && "no explicit binding");
50 if (VkBinding)
51 return VkBinding->getBinding();
52 if (RegBinding && RegBinding->hasRegisterSlot())
53 return RegBinding->getSlotNumber();
54 llvm_unreachable("no explicit binding");
55 }
56
57 unsigned getSpace() const {
58 if (VkBinding)
59 return VkBinding->getSet();
60 if (RegBinding)
61 return RegBinding->getSpaceNumber();
62 return 0;
63 }
64
65 bool hasImplicitOrderID() const {
66 return RegBinding && RegBinding->hasImplicitBindingOrderID();
67 }
68
69 unsigned getImplicitOrderID() const {
70 assert(hasImplicitOrderID());
71 return RegBinding->getImplicitBindingOrderID();
72 }
73
74 void setImplicitOrderID(unsigned Value) const {
75 assert(hasBinding() && !isExplicit() && !hasImplicitOrderID());
76 RegBinding->setImplicitBindingOrderID(Value);
77 }
78 void setCounterImplicitOrderID(unsigned Value) const {
80 RegBinding->setImplicitCounterBindingOrderID(Value);
81 }
82
84 return RegBinding && RegBinding->hasImplicitCounterBindingOrderID();
85 }
86
87 unsigned getCounterImplicitOrderID() const {
89 return RegBinding->getImplicitCounterBindingOrderID();
90 }
91};
92
93inline uint32_t getResourceDimensions(llvm::dxil::ResourceDimension Dim) {
94 switch (Dim) {
95 case llvm::dxil::ResourceDimension::Dim1D:
96 return 1;
97 break;
98 case llvm::dxil::ResourceDimension::Dim2D:
99 return 2;
100 break;
101 case llvm::dxil::ResourceDimension::Dim3D:
102 case llvm::dxil::ResourceDimension::Cube:
103 return 3;
104 break;
105 case llvm::dxil::ResourceDimension::Unknown:
106 llvm_unreachable(
107 "We cannot get the dimension of a resource with unknown dimension.");
108 }
109 llvm_unreachable("Unhandled llvm::dxil::ResourceDimension enum.");
110}
111
112// Returns true if the second field of the record is a counter resource handle
113inline bool hasCounterHandle(const CXXRecordDecl *RD) {
114 if (RD->field_empty())
115 return false;
116 auto It = std::next(RD->field_begin());
117 if (It == RD->field_end())
118 return false;
119 const FieldDecl *SecondField = *It;
120 if (const auto *ResTy =
121 SecondField->getType()->getAs<HLSLAttributedResourceType>()) {
122 return ResTy->getAttrs().IsCounter;
123 }
124 return false;
125}
126
127// Helper class for building a name of a global resource variable that
128// gets created for a resource embedded in a struct or class. This will
129// also be used from CodeGen to build a name that matches the resource
130// access with the corresponding declaration.
134
135 inline static constexpr std::string_view BaseClassDelim = "::";
136 inline static constexpr std::string_view FieldDelim = ".";
137 inline static constexpr std::string_view ArrayIndexDelim = FieldDelim;
138
139public:
140 EmbeddedResourceNameBuilder(llvm::StringRef BaseName) : Name(BaseName) {}
142
143 void pushName(llvm::StringRef N) { pushName(N, FieldDelim); }
144 void pushBaseName(llvm::StringRef N);
145 void pushArrayIndex(uint64_t Index);
146 void pushBaseNameHierarchy(CXXRecordDecl *DerivedRD, CXXRecordDecl *BaseRD);
147
148 void pop() {
149 assert(!Offsets.empty() && "no name to pop");
150 Name.resize(Offsets.pop_back_val());
151 }
152
154 return &AST.Idents.get(Name);
155 }
156
157private:
158 void pushName(llvm::StringRef N, llvm::StringRef Delim);
159};
160
161} // namespace hlsl
162
163} // namespace clang
164
165#endif // LLVM_CLANG_AST_HLSLRESOURCE_H
Defines the clang::ASTContext interface.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:227
IdentifierTable & Idents
Definition ASTContext.h:805
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:924
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
T * getAttr() const
Definition DeclBase.h:581
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:547
Represents a member of a struct/union/class.
Definition Decl.h:3178
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
field_iterator field_end() const
Definition Decl.h:4549
bool field_empty() const
Definition Decl.h:4554
field_iterator field_begin() const
Definition Decl.cpp:5270
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9266
QualType getType() const
Definition Decl.h:723
EmbeddedResourceNameBuilder(llvm::StringRef BaseName)
void pushBaseNameHierarchy(CXXRecordDecl *DerivedRD, CXXRecordDecl *BaseRD)
IdentifierInfo * getNameAsIdentifier(ASTContext &AST) const
Defines the clang::TargetInfo interface.
uint32_t getResourceDimensions(llvm::dxil::ResourceDimension Dim)
bool hasCounterHandle(const CXXRecordDecl *RD)
The JSON file list parser is used to communicate input to InstallAPI.
void setCounterImplicitOrderID(unsigned Value) const
unsigned getCounterImplicitOrderID() const
HLSLResourceBindingAttr * RegBinding
void setImplicitOrderID(unsigned Value) const