Skip to content

Commit 6bc286e

Browse files
committed
add recursive flag setting code, and parse hlsl semantics inside struct members, remove is_member
1 parent 91d050f commit 6bc286e

File tree

4 files changed

+76
-7
lines changed

4 files changed

+76
-7
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4366,7 +4366,7 @@ def HLSLSV_GroupIndex: HLSLAnnotationAttr {
43664366

43674367
def HLSLResourceBinding: InheritableAttr {
43684368
let Spellings = [HLSLSemantic<"register">];
4369-
let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar]>;
4369+
let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar], ErrorDiag>;
43704370
let LangOpts = [HLSL];
43714371
let Args = [StringArgument<"Slot">, StringArgument<"Space", 1>];
43724372
let Documentation = [HLSLResourceBindingDocs];

clang/lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4859,6 +4859,8 @@ void Parser::ParseStructDeclaration(
48594859

48604860
// If attributes exist after the declarator, parse them.
48614861
MaybeParseGNUAttributes(DeclaratorInfo.D);
4862+
if (getLangOpts().HLSL)
4863+
MaybeParseHLSLSemantics(DeclaratorInfo.D);
48624864

48634865
// We're done with this declarator; invoke the callback.
48644866
FieldsCallback(DeclaratorInfo);

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2649,6 +2649,9 @@ bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
26492649
else
26502650
DeclaratorInfo.SetIdentifier(nullptr, Tok.getLocation());
26512651

2652+
if (getLangOpts().HLSL)
2653+
MaybeParseHLSLSemantics(DeclaratorInfo);
2654+
26522655
if (!DeclaratorInfo.isFunctionDeclarator() && TryConsumeToken(tok::colon)) {
26532656
assert(DeclaratorInfo.isPastIdentifier() &&
26542657
"don't know where identifier would go yet?");

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7340,14 +7340,13 @@ struct register_binding_flags {
73407340
bool other = false;
73417341
bool basic = false;
73427342

7343-
bool srv;
7344-
bool uav;
7345-
bool cbv;
7346-
bool sampler;
7343+
bool srv = false;
7344+
bool uav = false;
7345+
bool cbv = false;
7346+
bool sampler = false;
73477347

73487348
bool contains_numeric = false;
73497349
bool default_globals = false;
7350-
bool is_member = false;
73517350
};
73527351

73537352
bool isDeclaredWithinCOrTBuffer(const Decl *decl) {
@@ -7394,6 +7393,63 @@ const HLSLResourceAttr *getHLSLResourceAttrFromVarDecl(VarDecl *SamplerUAVOrSRV)
73947393
return Attr;
73957394
}
73967395

7396+
void traverseType(QualType T, register_binding_flags &r) {
7397+
if (T->isIntegralOrEnumerationType() || T->isFloatingType()) {
7398+
r.contains_numeric = true;
7399+
return;
7400+
} else if (const RecordType *RT = T->getAs<RecordType>()) {
7401+
RecordDecl *SubRD = RT->getDecl();
7402+
if (auto TDecl = dyn_cast<ClassTemplateSpecializationDecl>(SubRD)) {
7403+
auto TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl();
7404+
TheRecordDecl = TheRecordDecl->getCanonicalDecl();
7405+
const auto *Attr = TheRecordDecl->getAttr<HLSLResourceAttr>();
7406+
llvm::hlsl::ResourceClass DeclResourceClass = Attr->getResourceClass();
7407+
switch (DeclResourceClass) {
7408+
case llvm::hlsl::ResourceClass::SRV: {
7409+
r.srv = true;
7410+
break;
7411+
}
7412+
case llvm::hlsl::ResourceClass::UAV: {
7413+
r.uav = true;
7414+
break;
7415+
}
7416+
case llvm::hlsl::ResourceClass::CBuffer: {
7417+
r.cbv = true;
7418+
break;
7419+
}
7420+
case llvm::hlsl::ResourceClass::Sampler: {
7421+
r.sampler = true;
7422+
break;
7423+
}
7424+
case llvm::hlsl::ResourceClass::Invalid: {
7425+
llvm_unreachable("Resource class should be valid.");
7426+
break;
7427+
}
7428+
}
7429+
}
7430+
7431+
else if (SubRD->isCompleteDefinition()) {
7432+
for (auto Field : SubRD->fields()) {
7433+
QualType T = Field->getType();
7434+
traverseType(T, r);
7435+
}
7436+
}
7437+
}
7438+
}
7439+
7440+
void setResourceClassFlagsFromRecordDecl(register_binding_flags &r,
7441+
const RecordDecl *RD) {
7442+
if (!RD)
7443+
return;
7444+
7445+
if (RD->isCompleteDefinition()) {
7446+
for (auto Field : RD->fields()) {
7447+
QualType T = Field->getType();
7448+
traverseType(T, r);
7449+
}
7450+
}
7451+
}
7452+
73977453
register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) {
73987454
register_binding_flags r;
73997455
if (!isDeclaredWithinCOrTBuffer(D)) {
@@ -7452,7 +7508,12 @@ register_binding_flags HLSLFillRegisterBindingFlags(Sema &S, Decl *D) {
74527508
r.basic = true;
74537509
else if (SamplerUAVOrSRV->getType()->isAggregateType()) {
74547510
r.udt = true;
7455-
// recurse through members, set appropriate resource class flags.
7511+
QualType VarType = SamplerUAVOrSRV->getType();
7512+
if (const RecordType *RT = VarType->getAs<RecordType>()) {
7513+
const RecordDecl *RD = RT->getDecl();
7514+
// recurse through members, set appropriate resource class flags.
7515+
setResourceClassFlagsFromRecordDecl(r, RD);
7516+
}
74567517
}
74577518
else
74587519
r.other = true;
@@ -7479,6 +7540,9 @@ static void DiagnoseHLSLResourceRegType(Sema &S, SourceLocation &ArgLoc,
74797540

74807541
static void handleHLSLResourceBindingAttr(Sema &S, Decl *D,
74817542
const ParsedAttr &AL) {
7543+
if (S.RequireCompleteType(D->getBeginLoc(), cast<ValueDecl>(D)->getType(),
7544+
diag::err_incomplete_type))
7545+
return;
74827546
StringRef Space = "space0";
74837547
StringRef Slot = "";
74847548

0 commit comments

Comments
 (0)