aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaHLSL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaHLSL.cpp')
-rw-r--r--clang/lib/Sema/SemaHLSL.cpp69
1 files changed, 43 insertions, 26 deletions
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index e59849a..b4bbe02 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -234,7 +234,7 @@ static unsigned calculateLegacyCbufferSize(const ASTContext &Context,
constexpr unsigned CBufferAlign = 16;
if (const RecordType *RT = T->getAs<RecordType>()) {
unsigned Size = 0;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
for (const FieldDecl *Field : RD->fields()) {
QualType Ty = Field->getType();
unsigned FieldSize = calculateLegacyCbufferSize(Context, Ty);
@@ -337,16 +337,9 @@ static bool isZeroSizedArray(const ConstantArrayType *CAT) {
return CAT != nullptr;
}
-// Returns true if the record type is an HLSL resource class or an array of
-// resource classes
-static bool isResourceRecordTypeOrArrayOf(const Type *Ty) {
- while (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty))
- Ty = CAT->getArrayElementTypeNoTypeQual();
- return HLSLAttributedResourceType::findHandleTypeOnResource(Ty) != nullptr;
-}
-
static bool isResourceRecordTypeOrArrayOf(VarDecl *VD) {
- return isResourceRecordTypeOrArrayOf(VD->getType().getTypePtr());
+ const Type *Ty = VD->getType().getTypePtr();
+ return Ty->isHLSLResourceRecord() || Ty->isHLSLResourceRecordArray();
}
// Returns true if the type is a leaf element type that is not valid to be
@@ -355,7 +348,7 @@ static bool isResourceRecordTypeOrArrayOf(VarDecl *VD) {
// type or if it is a record type that needs to be inspected further.
static bool isInvalidConstantBufferLeafElementType(const Type *Ty) {
Ty = Ty->getUnqualifiedDesugaredType();
- if (isResourceRecordTypeOrArrayOf(Ty))
+ if (Ty->isHLSLResourceRecord() || Ty->isHLSLResourceRecordArray())
return true;
if (Ty->isRecordType())
return Ty->getAsCXXRecordDecl()->isEmpty();
@@ -373,7 +366,7 @@ static bool isInvalidConstantBufferLeafElementType(const Type *Ty) {
// needs to be created for HLSL Buffer use that will exclude these unwanted
// declarations (see createHostLayoutStruct function).
static bool requiresImplicitBufferLayoutStructure(const CXXRecordDecl *RD) {
- if (RD->getTypeForDecl()->isHLSLIntangibleType() || RD->isEmpty())
+ if (RD->isHLSLIntangible() || RD->isEmpty())
return true;
// check fields
for (const FieldDecl *Field : RD->fields()) {
@@ -458,7 +451,7 @@ static FieldDecl *createFieldForHostLayoutStruct(Sema &S, const Type *Ty,
RD = createHostLayoutStruct(S, RD);
if (!RD)
return nullptr;
- Ty = RD->getTypeForDecl();
+ Ty = S.Context.getCanonicalTagType(RD)->getTypePtr();
}
}
@@ -508,8 +501,8 @@ static CXXRecordDecl *createHostLayoutStruct(Sema &S,
if (requiresImplicitBufferLayoutStructure(BaseDecl)) {
BaseDecl = createHostLayoutStruct(S, BaseDecl);
if (BaseDecl) {
- TypeSourceInfo *TSI = AST.getTrivialTypeSourceInfo(
- QualType(BaseDecl->getTypeForDecl(), 0));
+ TypeSourceInfo *TSI =
+ AST.getTrivialTypeSourceInfo(AST.getCanonicalTagType(BaseDecl));
Base = CXXBaseSpecifier(SourceRange(), false, StructDecl->isClass(),
AS_none, TSI, SourceLocation());
}
@@ -597,8 +590,9 @@ void SemaHLSL::ActOnFinishBuffer(Decl *Dcl, SourceLocation RBrace) {
// create buffer layout struct
createHostLayoutStructForBuffer(SemaRef, BufDecl);
+ HLSLVkBindingAttr *VkBinding = Dcl->getAttr<HLSLVkBindingAttr>();
HLSLResourceBindingAttr *RBA = Dcl->getAttr<HLSLResourceBindingAttr>();
- if (!RBA || !RBA->hasRegisterSlot()) {
+ if (!VkBinding && (!RBA || !RBA->hasRegisterSlot())) {
SemaRef.Diag(Dcl->getLocation(), diag::warn_hlsl_implicit_binding);
// Use HLSLResourceBindingAttr to transfer implicit binding order_ID
// to codegen. If it does not exist, create an implicit attribute.
@@ -1496,6 +1490,23 @@ void SemaHLSL::handleVkConstantIdAttr(Decl *D, const ParsedAttr &AL) {
D->addAttr(NewAttr);
}
+void SemaHLSL::handleVkBindingAttr(Decl *D, const ParsedAttr &AL) {
+ // The vk::binding attribute only applies to SPIR-V.
+ if (!getASTContext().getTargetInfo().getTriple().isSPIRV())
+ return;
+
+ uint32_t Binding = 0;
+ if (!SemaRef.checkUInt32Argument(AL, AL.getArgAsExpr(0), Binding))
+ return;
+ uint32_t Set = 0;
+ if (AL.getNumArgs() > 1 &&
+ !SemaRef.checkUInt32Argument(AL, AL.getArgAsExpr(1), Set))
+ return;
+
+ D->addAttr(::new (getASTContext())
+ HLSLVkBindingAttr(getASTContext(), AL, Binding, Set));
+}
+
bool SemaHLSL::diagnoseInputIDType(QualType T, const ParsedAttr &AL) {
const auto *VT = T->getAs<VectorType>();
@@ -1825,7 +1836,7 @@ SemaHLSL::TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT) {
// requirements and adds them to Bindings
void SemaHLSL::collectResourceBindingsOnUserRecordDecl(const VarDecl *VD,
const RecordType *RT) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
for (FieldDecl *FD : RD->fields()) {
const Type *Ty = FD->getType()->getUnqualifiedDesugaredType();
@@ -3378,7 +3389,7 @@ bool SemaHLSL::ContainsBitField(QualType BaseTy) {
continue;
}
if (const auto *RT = dyn_cast<RecordType>(T)) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isUnion())
continue;
@@ -3579,7 +3590,7 @@ void SemaHLSL::deduceAddressSpace(VarDecl *Decl) {
return;
// Resource handles.
- if (isResourceRecordTypeOrArrayOf(Type->getUnqualifiedDesugaredType()))
+ if (Type->isHLSLResourceRecord() || Type->isHLSLResourceRecordArray())
return;
// Only static globals belong to the Private address space.
@@ -3619,10 +3630,7 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
if (VD->getType()->isHLSLIntangibleType())
collectResourceBindingsOnVarDecl(VD);
- const Type *VarType = VD->getType().getTypePtr();
- while (VarType->isArrayType())
- VarType = VarType->getArrayElementTypeNoTypeQual();
- if (VarType->isHLSLResourceRecord() ||
+ if (isResourceRecordTypeOrArrayOf(VD) ||
VD->hasAttr<HLSLVkConstantIdAttr>()) {
// Make the variable for resources static. The global externally visible
// storage is accessed through the handle, which is a member. The variable
@@ -3660,8 +3668,12 @@ static bool initVarDeclWithCtor(Sema &S, VarDecl *VD,
bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) {
std::optional<uint32_t> RegisterSlot;
uint32_t SpaceNo = 0;
+ HLSLVkBindingAttr *VkBinding = VD->getAttr<HLSLVkBindingAttr>();
HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
- if (RBA) {
+ if (VkBinding) {
+ RegisterSlot = VkBinding->getBinding();
+ SpaceNo = VkBinding->getSet();
+ } else if (RBA) {
if (RBA->hasRegisterSlot())
RegisterSlot = RBA->getSlotNumber();
SpaceNo = RBA->getSpaceNumber();
@@ -3764,6 +3776,9 @@ void SemaHLSL::processExplicitBindingsOnDecl(VarDecl *VD) {
bool HasBinding = false;
for (Attr *A : VD->attrs()) {
+ if (isa<HLSLVkBindingAttr>(A))
+ HasBinding = true;
+
HLSLResourceBindingAttr *RBA = dyn_cast<HLSLResourceBindingAttr>(A);
if (!RBA || !RBA->hasRegisterSlot())
continue;
@@ -3894,7 +3909,8 @@ class InitListTransformer {
}
while (!RecordTypes.empty()) {
const RecordType *RT = RecordTypes.pop_back_val();
- for (auto *FD : RT->getDecl()->fields()) {
+ for (auto *FD :
+ RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) {
DeclAccessPair Found = DeclAccessPair::make(FD, FD->getAccess());
DeclarationNameInfo NameInfo(FD->getDeclName(), E->getBeginLoc());
ExprResult Res = S.BuildFieldReferenceExpr(
@@ -3942,7 +3958,8 @@ class InitListTransformer {
}
while (!RecordTypes.empty()) {
const RecordType *RT = RecordTypes.pop_back_val();
- for (auto *FD : RT->getDecl()->fields()) {
+ for (auto *FD :
+ RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) {
Inits.push_back(generateInitListsImpl(FD->getType()));
}
}