Skip to content
Merged
38 changes: 38 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -4593,6 +4593,44 @@ def HLSLResourceBinding: InheritableAttr {
let LangOpts = [HLSL];
let Args = [StringArgument<"Slot">, StringArgument<"Space", 1>];
let Documentation = [HLSLResourceBindingDocs];
let AdditionalMembers = [{
enum class RegisterType : unsigned { SRV, UAV, CBuffer, Sampler, C, I, Invalid };

RegisterType RegType;
unsigned SlotNumber;
unsigned SpaceNumber;

// Size of the binding
// 0 == not set
//-1 == unbounded
int Size;

void setBinding(RegisterType RT, unsigned SlotNum, unsigned SpaceNum, int Size = 0) {
RegType = RT;
SlotNumber = SlotNum;
SpaceNumber = SpaceNum;
}
RegisterType getRegisterType() {
return RegType;
}
unsigned getSlotNumber() {
return SlotNumber;
}
unsigned getSpaceNumber() {
return SpaceNumber;
}
unsigned getSize() {
assert(Size == -1 || Size > 0 && "size not set");
return Size;
}
void setSize(int N) {
assert(N == -1 || N > 0 && "unexpected size value");
Size = N;
}
bool isSizeUnbounded() {
return Size == -1;
}
}];
}

def HLSLPackOffset: HLSLAnnotationAttr {
Expand Down
59 changes: 59 additions & 0 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,62 @@ class AttributeCommonInfo;
class IdentifierInfo;
class ParsedAttr;
class Scope;
class VarDecl;

using llvm::dxil::ResourceClass;

// FIXME: This can be hidden (as static function in SemaHLSL.cpp) once we no
// longer need to create builtin buffer types in HLSLExternalSemaSource.
bool CreateHLSLAttributedResourceType(
Sema &S, QualType Wrapped, ArrayRef<const Attr *> AttrList,
QualType &ResType, HLSLAttributedResourceLocInfo *LocInfo = nullptr);

enum class BindingType : uint8_t { NotAssigned, Explicit, Implicit };

// DeclBindingInfo struct stores information about required/assigned resource
// binding onon a declaration for specific resource class.
struct DeclBindingInfo {
const VarDecl *Decl;
ResourceClass ResClass;
int Size; // -1 == unbounded array
const HLSLResourceBindingAttr *Attr;
BindingType BindType;

DeclBindingInfo(const VarDecl *Decl, ResourceClass ResClass, int Size = 0,
BindingType BindType = BindingType::NotAssigned,
const HLSLResourceBindingAttr *Attr = nullptr)
: Decl(Decl), ResClass(ResClass), Size(Size), Attr(Attr),
BindType(BindType) {}

void setBindingAttribute(HLSLResourceBindingAttr *A, BindingType BT) {
assert(Attr == nullptr && BindType == BindingType::NotAssigned &&
"binding attribute already assigned");
Attr = A;
BindType = BT;
}
};

// ResourceBindings class stores information about all resource bindings
// in a shader. It is used for binding diagnostics and implicit binding
// assigments.
class ResourceBindings {
public:
DeclBindingInfo *addDeclBindingInfo(const VarDecl *VD, ResourceClass ResClass,
int Size);
DeclBindingInfo *getDeclBindingInfo(const VarDecl *VD,
ResourceClass ResClass);
bool hasBindingInfoForDecl(const VarDecl *VD);

private:
// List of all resource bindings required by the shader.
// A global declaration can have multiple bindings for different
// resource classes. They are all stored sequentially in this list.
// The DeclToBindingListIndex hashtable maps a declaration to the
// index of the first binding info in the list.
llvm::SmallVector<DeclBindingInfo> BindingsList;
llvm::DenseMap<const VarDecl *, unsigned> DeclToBindingListIndex;
};

class SemaHLSL : public SemaBase {
public:
SemaHLSL(Sema &S);
Expand All @@ -55,6 +104,7 @@ class SemaHLSL : public SemaBase {
mergeParamModifierAttr(Decl *D, const AttributeCommonInfo &AL,
HLSLParamModifierAttr::Spelling Spelling);
void ActOnTopLevelFunction(FunctionDecl *FD);
void ActOnVariableDeclarator(VarDecl *VD);
void CheckEntryPoint(FunctionDecl *FD);
void CheckSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
const HLSLAnnotationAttr *AnnotationAttr);
Expand Down Expand Up @@ -102,6 +152,15 @@ class SemaHLSL : public SemaBase {
llvm::DenseMap<const HLSLAttributedResourceType *,
HLSLAttributedResourceLocInfo>
LocsForHLSLAttributedResources;

// List of all resource bindings
ResourceBindings Bindings;

private:
void FindResourcesOnVarDecl(VarDecl *D);
void FindResourcesOnUserRecordDecl(const VarDecl *VD, const RecordType *RT,
int Size);
void ProcessExplicitBindingsOnDecl(VarDecl *D);
};

} // namespace clang
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7876,6 +7876,9 @@ NamedDecl *Sema::ActOnVariableDeclarator(
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(S, NewVD, D);

if (getLangOpts().HLSL)
HLSL().ActOnVariableDeclarator(NewVD);

// FIXME: This is probably the wrong location to be doing this and we should
// probably be doing this for more attributes (especially for function
// pointer attributes such as format, warn_unused_result, etc.). Ideally
Expand Down
Loading
Loading