@@ -119,6 +119,40 @@ static ResourceClass getResourceClass(RegisterType RT) {
119119 llvm_unreachable (" unexpected RegisterType value" );
120120}
121121
122+ static Builtin::ID getSpecConstBuiltinId (QualType Type) {
123+ const auto *BT = dyn_cast<BuiltinType>(Type);
124+ if (!BT) {
125+ if (!Type->isEnumeralType ())
126+ return Builtin::NotBuiltin;
127+ return Builtin::BI__builtin_get_spirv_spec_constant_int;
128+ }
129+
130+ switch (BT->getKind ()) {
131+ case BuiltinType::Bool:
132+ return Builtin::BI__builtin_get_spirv_spec_constant_bool;
133+ case BuiltinType::Short:
134+ return Builtin::BI__builtin_get_spirv_spec_constant_short;
135+ case BuiltinType::Int:
136+ return Builtin::BI__builtin_get_spirv_spec_constant_int;
137+ case BuiltinType::LongLong:
138+ return Builtin::BI__builtin_get_spirv_spec_constant_longlong;
139+ case BuiltinType::UShort:
140+ return Builtin::BI__builtin_get_spirv_spec_constant_ushort;
141+ case BuiltinType::UInt:
142+ return Builtin::BI__builtin_get_spirv_spec_constant_uint;
143+ case BuiltinType::ULongLong:
144+ return Builtin::BI__builtin_get_spirv_spec_constant_ulonglong;
145+ case BuiltinType::Half:
146+ return Builtin::BI__builtin_get_spirv_spec_constant_half;
147+ case BuiltinType::Float:
148+ return Builtin::BI__builtin_get_spirv_spec_constant_float;
149+ case BuiltinType::Double:
150+ return Builtin::BI__builtin_get_spirv_spec_constant_double;
151+ default :
152+ return Builtin::NotBuiltin;
153+ }
154+ }
155+
122156DeclBindingInfo *ResourceBindings::addDeclBindingInfo (const VarDecl *VD,
123157 ResourceClass ResClass) {
124158 assert (getDeclBindingInfo (VD, ResClass) == nullptr &&
@@ -607,6 +641,41 @@ HLSLWaveSizeAttr *SemaHLSL::mergeWaveSizeAttr(Decl *D,
607641 return Result;
608642}
609643
644+ HLSLVkConstantIdAttr *
645+ SemaHLSL::mergeVkConstantIdAttr (Decl *D, const AttributeCommonInfo &AL,
646+ int Id) {
647+
648+ auto &TargetInfo = getASTContext ().getTargetInfo ();
649+ if (TargetInfo.getTriple ().getArch () != llvm::Triple::spirv) {
650+ Diag (AL.getLoc (), diag::warn_attribute_ignored) << AL;
651+ return nullptr ;
652+ }
653+
654+ auto *VD = cast<VarDecl>(D);
655+
656+ if (getSpecConstBuiltinId (VD->getType ()) == Builtin::NotBuiltin) {
657+ Diag (VD->getLocation (), diag::err_specialization_const_is_not_int_or_float);
658+ return nullptr ;
659+ }
660+
661+ if (!VD->getType ().isConstQualified ()) {
662+ Diag (VD->getLocation (), diag::err_specialization_const_missing_const);
663+ return nullptr ;
664+ }
665+
666+ if (HLSLVkConstantIdAttr *CI = D->getAttr <HLSLVkConstantIdAttr>()) {
667+ if (CI->getId () != Id) {
668+ Diag (CI->getLocation (), diag::err_hlsl_attribute_param_mismatch) << AL;
669+ Diag (AL.getLoc (), diag::note_conflicting_attribute);
670+ }
671+ return nullptr ;
672+ }
673+
674+ HLSLVkConstantIdAttr *Result =
675+ ::new (getASTContext ()) HLSLVkConstantIdAttr (getASTContext (), AL, Id);
676+ return Result;
677+ }
678+
610679HLSLShaderAttr *
611680SemaHLSL::mergeShaderAttr (Decl *D, const AttributeCommonInfo &AL,
612681 llvm::Triple::EnvironmentType ShaderType) {
@@ -1125,6 +1194,15 @@ void SemaHLSL::handleVkExtBuiltinInputAttr(Decl *D, const ParsedAttr &AL) {
11251194 HLSLVkExtBuiltinInputAttr (getASTContext (), AL, ID));
11261195}
11271196
1197+ void SemaHLSL::handleVkConstantIdAttr (Decl *D, const ParsedAttr &AL) {
1198+ uint32_t Id;
1199+ if (!SemaRef.checkUInt32Argument (AL, AL.getArgAsExpr (0 ), Id))
1200+ return ;
1201+ HLSLVkConstantIdAttr *NewAttr = mergeVkConstantIdAttr (D, AL, Id);
1202+ if (NewAttr)
1203+ D->addAttr (NewAttr);
1204+ }
1205+
11281206bool SemaHLSL::diagnoseInputIDType (QualType T, const ParsedAttr &AL) {
11291207 const auto *VT = T->getAs <VectorType>();
11301208
@@ -3154,6 +3232,7 @@ static bool IsDefaultBufferConstantDecl(VarDecl *VD) {
31543232 return VD->getDeclContext ()->isTranslationUnit () &&
31553233 QT.getAddressSpace () == LangAS::Default &&
31563234 VD->getStorageClass () != SC_Static &&
3235+ !VD->hasAttr <HLSLVkConstantIdAttr>() &&
31573236 !isInvalidConstantBufferLeafElementType (QT.getTypePtr ());
31583237}
31593238
@@ -3221,7 +3300,8 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
32213300 const Type *VarType = VD->getType ().getTypePtr ();
32223301 while (VarType->isArrayType ())
32233302 VarType = VarType->getArrayElementTypeNoTypeQual ();
3224- if (VarType->isHLSLResourceRecord ()) {
3303+ if (VarType->isHLSLResourceRecord () ||
3304+ VD->hasAttr <HLSLVkConstantIdAttr>()) {
32253305 // Make the variable for resources static. The global externally visible
32263306 // storage is accessed through the handle, which is a member. The variable
32273307 // itself is not externally visible.
@@ -3644,3 +3724,41 @@ bool SemaHLSL::transformInitList(const InitializedEntity &Entity,
36443724 Init->updateInit (Ctx, I, NewInit->getInit (I));
36453725 return true ;
36463726}
3727+
3728+ bool SemaHLSL::handleInitialization (VarDecl *VDecl, Expr *&Init) {
3729+ const HLSLVkConstantIdAttr *ConstIdAttr =
3730+ VDecl->getAttr <HLSLVkConstantIdAttr>();
3731+ if (!ConstIdAttr)
3732+ return true ;
3733+
3734+ ASTContext &Context = SemaRef.getASTContext ();
3735+
3736+ APValue InitValue;
3737+ if (!Init->isCXX11ConstantExpr (Context, &InitValue)) {
3738+ Diag (VDecl->getLocation (), diag::err_specialization_const_lit_init);
3739+ VDecl->setInvalidDecl ();
3740+ return false ;
3741+ }
3742+
3743+ Builtin::ID BID = getSpecConstBuiltinId (VDecl->getType ());
3744+
3745+ // Argument 1: The ID from the attribute
3746+ int ConstantID = ConstIdAttr->getId ();
3747+ llvm::APInt IDVal (Context.getIntWidth (Context.IntTy ), ConstantID);
3748+ Expr *IdExpr = IntegerLiteral::Create (Context, IDVal, Context.IntTy ,
3749+ ConstIdAttr->getLocation ());
3750+
3751+ SmallVector<Expr *, 2 > Args = {IdExpr, Init};
3752+ Expr *C = SemaRef.BuildBuiltinCallExpr (Init->getExprLoc (), BID, Args);
3753+ if (C->getType ()->getCanonicalTypeUnqualified () !=
3754+ VDecl->getType ()->getCanonicalTypeUnqualified ()) {
3755+ C = SemaRef
3756+ .BuildCStyleCastExpr (SourceLocation (),
3757+ Context.getTrivialTypeSourceInfo (
3758+ Init->getType (), Init->getExprLoc ()),
3759+ SourceLocation (), C)
3760+ .get ();
3761+ }
3762+ Init = C;
3763+ return true ;
3764+ }
0 commit comments