@@ -2427,6 +2427,20 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
24272427 TheCall->setType (ResourceTy);
24282428 break ;
24292429 }
2430+ case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
2431+ ASTContext &AST = SemaRef.getASTContext ();
2432+ if (SemaRef.checkArgCount (TheCall, 5 ) ||
2433+ CheckResourceHandle (&SemaRef, TheCall, 0 ) ||
2434+ CheckArgTypeMatches (&SemaRef, TheCall->getArg (1 ), AST.UnsignedIntTy ) ||
2435+ CheckArgTypeMatches (&SemaRef, TheCall->getArg (2 ), AST.IntTy ) ||
2436+ CheckArgTypeMatches (&SemaRef, TheCall->getArg (3 ), AST.UnsignedIntTy ) ||
2437+ CheckArgTypeMatches (&SemaRef, TheCall->getArg (4 ), AST.UnsignedIntTy ))
2438+ return true ;
2439+ // use the type of the handle (arg0) as a return type
2440+ QualType ResourceTy = TheCall->getArg (0 )->getType ();
2441+ TheCall->setType (ResourceTy);
2442+ break ;
2443+ }
24302444 case Builtin::BI__builtin_hlsl_and:
24312445 case Builtin::BI__builtin_hlsl_or: {
24322446 if (SemaRef.checkArgCount (TheCall, 2 ))
@@ -3258,8 +3272,10 @@ static bool initVarDeclWithCtor(Sema &S, VarDecl *VD,
32583272 VD->getLocation (), SourceLocation (), SourceLocation ());
32593273
32603274 InitializationSequence InitSeq (S, Entity, Kind, Args);
3261- ExprResult Init = InitSeq.Perform (S, Entity, Kind, Args);
3275+ if (InitSeq.Failed ())
3276+ return false ;
32623277
3278+ ExprResult Init = InitSeq.Perform (S, Entity, Kind, Args);
32633279 if (!Init.get ())
32643280 return false ;
32653281
@@ -3269,27 +3285,42 @@ static bool initVarDeclWithCtor(Sema &S, VarDecl *VD,
32693285 return true ;
32703286}
32713287
3272- static bool initGlobalResourceDecl (Sema &S, VarDecl *VD) {
3288+ bool SemaHLSL::initGlobalResourceDecl (VarDecl *VD) {
3289+ std::optional<uint32_t > RegisterSlot;
3290+ uint32_t SpaceNo = 0 ;
32733291 HLSLResourceBindingAttr *RBA = VD->getAttr <HLSLResourceBindingAttr>();
3274- if (!RBA || RBA->isImplicit ())
3275- // FIXME: add support for implicit binding (llvm/llvm-project#110722)
3276- return false ;
3292+ if (RBA) {
3293+ if (!RBA->isImplicit ())
3294+ RegisterSlot = RBA->getSlotNumber ();
3295+ SpaceNo = RBA->getSpaceNumber ();
3296+ }
32773297
3278- ASTContext &AST = S .getASTContext ();
3298+ ASTContext &AST = SemaRef .getASTContext ();
32793299 uint64_t UIntTySize = AST.getTypeSize (AST.UnsignedIntTy );
32803300 uint64_t IntTySize = AST.getTypeSize (AST.IntTy );
3281- Expr *Args[] = {
3282- IntegerLiteral::Create (AST, llvm::APInt (UIntTySize, RBA->getSlotNumber ()),
3283- AST.UnsignedIntTy , SourceLocation ()),
3284- IntegerLiteral::Create (AST,
3285- llvm::APInt (UIntTySize, RBA->getSpaceNumber ()),
3286- AST.UnsignedIntTy , SourceLocation ()),
3287- IntegerLiteral::Create (AST, llvm::APInt (IntTySize, 1 ), AST.IntTy ,
3288- SourceLocation ()),
3289- IntegerLiteral::Create (AST, llvm::APInt (UIntTySize, 0 ), AST.UnsignedIntTy ,
3290- SourceLocation ())};
3291-
3292- return initVarDeclWithCtor (S, VD, Args);
3301+ IntegerLiteral *One = IntegerLiteral::Create (AST, llvm::APInt (IntTySize, 1 ),
3302+ AST.IntTy , SourceLocation ());
3303+ IntegerLiteral *Zero = IntegerLiteral::Create (
3304+ AST, llvm::APInt (UIntTySize, 0 ), AST.UnsignedIntTy , SourceLocation ());
3305+ IntegerLiteral *Space =
3306+ IntegerLiteral::Create (AST, llvm::APInt (UIntTySize, SpaceNo),
3307+ AST.UnsignedIntTy , SourceLocation ());
3308+
3309+ // resource with explicit binding
3310+ if (RegisterSlot.has_value ()) {
3311+ IntegerLiteral *RegSlot = IntegerLiteral::Create (
3312+ AST, llvm::APInt (UIntTySize, RegisterSlot.value ()), AST.UnsignedIntTy ,
3313+ SourceLocation ());
3314+ Expr *Args[] = {RegSlot, Space, One, Zero};
3315+ return initVarDeclWithCtor (SemaRef, VD, Args);
3316+ }
3317+
3318+ // resource with explicit binding
3319+ IntegerLiteral *OrderId = IntegerLiteral::Create (
3320+ AST, llvm::APInt (UIntTySize, getNextImplicitBindingOrderID ()),
3321+ AST.UnsignedIntTy , SourceLocation ());
3322+ Expr *Args[] = {Space, One, Zero, OrderId};
3323+ return initVarDeclWithCtor (SemaRef, VD, Args);
32933324}
32943325
32953326// Returns true if the initialization has been handled.
@@ -3307,8 +3338,9 @@ bool SemaHLSL::ActOnUninitializedVarDecl(VarDecl *VD) {
33073338 // FIXME: We currectly support only simple resources - no arrays of resources
33083339 // or resources in user defined structs.
33093340 // (llvm/llvm-project#133835, llvm/llvm-project#133837)
3310- if (VD->getType ()->isHLSLResourceRecord ())
3311- return initGlobalResourceDecl (SemaRef, VD);
3341+ // Initialize resources at the global scope
3342+ if (VD->hasGlobalStorage () && VD->getType ()->isHLSLResourceRecord ())
3343+ return initGlobalResourceDecl (VD);
33123344
33133345 return false ;
33143346}
0 commit comments