@@ -505,6 +505,7 @@ static CXXRecordDecl *createHostLayoutStruct(Sema &S,
505505//  - empty structs
506506//  - zero-sized arrays
507507//  - non-variable declarations
508+ //  - SPIR-V specialization constants
508509//  The layout struct will be added to the HLSLBufferDecl declarations.
509510void  createHostLayoutStructForBuffer (Sema &S, HLSLBufferDecl *BufDecl) {
510511  ASTContext &AST = S.getASTContext ();
@@ -520,7 +521,8 @@ void createHostLayoutStructForBuffer(Sema &S, HLSLBufferDecl *BufDecl) {
520521  for  (Decl *D : BufDecl->buffer_decls ()) {
521522    VarDecl *VD = dyn_cast<VarDecl>(D);
522523    if  (!VD || VD->getStorageClass () == SC_Static ||
523-         VD->getType ().getAddressSpace () == LangAS::hlsl_groupshared)
524+         VD->getType ().getAddressSpace () == LangAS::hlsl_groupshared ||
525+         VD->hasAttr <HLSLVkConstantIdAttr>())
524526      continue ;
525527    const  Type *Ty = VD->getType ()->getUnqualifiedDesugaredType ();
526528    if  (FieldDecl *FD =
@@ -607,6 +609,54 @@ HLSLWaveSizeAttr *SemaHLSL::mergeWaveSizeAttr(Decl *D,
607609  return  Result;
608610}
609611
612+ HLSLVkConstantIdAttr *
613+ SemaHLSL::mergeVkConstantIdAttr (Decl *D, const  AttributeCommonInfo &AL,
614+                                 int  Id) {
615+ 
616+   auto  &TargetInfo = getASTContext ().getTargetInfo ();
617+   if  (TargetInfo.getTriple ().getArch () != llvm::Triple::spirv) {
618+     Diag (AL.getLoc (), diag::warn_attribute_ignored) << AL;
619+     return  nullptr ;
620+   }
621+ 
622+   auto  *VD = cast<VarDecl>(D);
623+ 
624+   if  (!VD->getType ()->isIntegerType () && !VD->getType ()->isFloatingType ()) {
625+     Diag (VD->getLocation (), diag::err_specialization_const_is_not_int_or_float);
626+     return  nullptr ;
627+   }
628+ 
629+   if  (VD->getStorageClass () != StorageClass::SC_None &&
630+       VD->getStorageClass () != StorageClass::SC_Extern) {
631+     Diag (VD->getLocation (),
632+          diag::err_specialization_const_is_not_externally_visible);
633+     return  nullptr ;
634+   }
635+ 
636+   if  (VD->isLocalVarDecl ()) {
637+     Diag (VD->getLocation (),
638+          diag::err_specialization_const_is_not_externally_visible);
639+     return  nullptr ;
640+   }
641+ 
642+   if  (!VD->getType ().isConstQualified ()) {
643+     Diag (VD->getLocation (), diag::err_specialization_const_missing_const);
644+     return  nullptr ;
645+   }
646+ 
647+   if  (HLSLVkConstantIdAttr *CI = D->getAttr <HLSLVkConstantIdAttr>()) {
648+     if  (CI->getId () != Id) {
649+       Diag (CI->getLocation (), diag::err_hlsl_attribute_param_mismatch) << AL;
650+       Diag (AL.getLoc (), diag::note_conflicting_attribute);
651+     }
652+     return  nullptr ;
653+   }
654+ 
655+   HLSLVkConstantIdAttr *Result =
656+       ::new  (getASTContext ()) HLSLVkConstantIdAttr (getASTContext (), AL, Id);
657+   return  Result;
658+ }
659+ 
610660HLSLShaderAttr *
611661SemaHLSL::mergeShaderAttr (Decl *D, const  AttributeCommonInfo &AL,
612662                          llvm::Triple::EnvironmentType ShaderType) {
@@ -1117,6 +1167,15 @@ void SemaHLSL::handleWaveSizeAttr(Decl *D, const ParsedAttr &AL) {
11171167    D->addAttr (NewAttr);
11181168}
11191169
1170+ void  SemaHLSL::handleVkConstantIdAttr (Decl *D, const  ParsedAttr &AL) {
1171+   uint32_t  Id;
1172+   if  (!SemaRef.checkUInt32Argument (AL, AL.getArgAsExpr (0 ), Id))
1173+     return ;
1174+   HLSLVkConstantIdAttr *NewAttr = mergeVkConstantIdAttr (D, AL, Id);
1175+   if  (NewAttr)
1176+     D->addAttr (NewAttr);
1177+ }
1178+ 
11201179bool  SemaHLSL::diagnoseInputIDType (QualType T, const  ParsedAttr &AL) {
11211180  const  auto  *VT = T->getAs <VectorType>();
11221181
0 commit comments