@@ -455,7 +455,7 @@ struct TemplateParameterListBuilder {
455
455
//
456
456
// BuiltinTypeMethodBuilder(Sema, RecordBuilder, "MethodName", ReturnType)
457
457
// .addParam("param_name", Type, InOutModifier)
458
- // .callBuiltin("buildin_name ", { BuiltinParams } )
458
+ // .callBuiltin("builtin_name ", BuiltinParams... )
459
459
// .finalizeMethod();
460
460
//
461
461
// The builder needs to have all of the method parameters before it can create
@@ -465,9 +465,9 @@ struct TemplateParameterListBuilder {
465
465
// referenced from the body building methods. Destructor or an explicit call to
466
466
// finalizeMethod() will complete the method definition.
467
467
//
468
- // The callBuiltin helper method passes in the resource handle as the first
469
- // argument of the builtin call. If this is not desired it takes a bool flag to
470
- // disable this .
468
+ // The callBuiltin helper method accepts constants via `Expr *` or placeholder
469
+ // value arguments to indicate which function arguments to forward to the
470
+ // builtin .
471
471
//
472
472
// If the method that is being built has a non-void return type the
473
473
// finalizeMethod will create a return statent with the value of the last
@@ -489,6 +489,24 @@ struct BuiltinTypeMethodBuilder {
489
489
llvm::SmallVector<MethodParam> Params;
490
490
llvm::SmallVector<Stmt *> StmtsList;
491
491
492
+ // Argument placeholders, inspired by std::placeholder. These are the indices
493
+ // of arguments to forward to `callBuiltin`, and additionally `Handle` which
494
+ // refers to the resource handle.
495
+ enum class PlaceHolder { _0, _1, _2, _3, Handle = 127 };
496
+
497
+ Expr *convertPlaceholder (PlaceHolder PH) {
498
+ if (PH == PlaceHolder::Handle)
499
+ return getResourceHandleExpr ();
500
+
501
+ ASTContext &AST = DeclBuilder.SemaRef .getASTContext ();
502
+ ParmVarDecl *ParamDecl = Method->getParamDecl (static_cast <unsigned >(PH));
503
+ return DeclRefExpr::Create (
504
+ AST, NestedNameSpecifierLoc (), SourceLocation (), ParamDecl, false ,
505
+ DeclarationNameInfo (ParamDecl->getDeclName (), SourceLocation ()),
506
+ ParamDecl->getType (), VK_PRValue);
507
+ }
508
+ Expr *convertPlaceholder (Expr *E) { return E; }
509
+
492
510
public:
493
511
BuiltinTypeMethodBuilder (Sema &S, BuiltinTypeDeclBuilder &DB, StringRef Name,
494
512
QualType ReturnTy)
@@ -502,7 +520,10 @@ struct BuiltinTypeMethodBuilder {
502
520
HLSLParamModifierAttr::Spelling Modifier =
503
521
HLSLParamModifierAttr::Keyword_in) {
504
522
assert (Method == nullptr && " Cannot add param, method already created" );
505
- llvm_unreachable (" not yet implemented" );
523
+ const IdentifierInfo &II = DeclBuilder.SemaRef .getASTContext ().Idents .get (
524
+ Name, tok::TokenKind::identifier);
525
+ Params.emplace_back (II, Ty, Modifier);
526
+ return *this ;
506
527
}
507
528
508
529
private:
@@ -564,9 +585,10 @@ struct BuiltinTypeMethodBuilder {
564
585
OK_Ordinary);
565
586
}
566
587
567
- BuiltinTypeMethodBuilder &
568
- callBuiltin (StringRef BuiltinName, ArrayRef<Expr *> CallParms,
569
- bool AddResourceHandleAsFirstArg = true ) {
588
+ template <typename ... Ts>
589
+ BuiltinTypeMethodBuilder &callBuiltin (StringRef BuiltinName, Ts... ArgSpecs) {
590
+ std::array<Expr *, sizeof ...(ArgSpecs)> Args{
591
+ convertPlaceholder (std::forward<Ts>(ArgSpecs))...};
570
592
571
593
// The first statement added to a method or access to 'this` creates the
572
594
// declaration.
@@ -579,16 +601,9 @@ struct BuiltinTypeMethodBuilder {
579
601
AST, NestedNameSpecifierLoc (), SourceLocation (), FD, false ,
580
602
FD->getNameInfo (), FD->getType (), VK_PRValue);
581
603
582
- SmallVector<Expr *> NewCallParms;
583
- if (AddResourceHandleAsFirstArg) {
584
- NewCallParms.push_back (getResourceHandleExpr ());
585
- for (auto *P : CallParms)
586
- NewCallParms.push_back (P);
587
- }
588
-
589
- Expr *Call = CallExpr::Create (
590
- AST, DRE, AddResourceHandleAsFirstArg ? NewCallParms : CallParms,
591
- FD->getReturnType (), VK_PRValue, SourceLocation (), FPOptionsOverride ());
604
+ Expr *Call =
605
+ CallExpr::Create (AST, DRE, Args, FD->getReturnType (), VK_PRValue,
606
+ SourceLocation (), FPOptionsOverride ());
592
607
StmtsList.push_back (Call);
593
608
return *this ;
594
609
}
@@ -656,18 +671,20 @@ BuiltinTypeDeclBuilder::addSimpleTemplateParams(ArrayRef<StringRef> Names,
656
671
}
657
672
658
673
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addIncrementCounterMethod () {
674
+ using PH = BuiltinTypeMethodBuilder::PlaceHolder;
659
675
return BuiltinTypeMethodBuilder (SemaRef, *this , " IncrementCounter" ,
660
676
SemaRef.getASTContext ().UnsignedIntTy )
661
- .callBuiltin (" __builtin_hlsl_buffer_update_counter" ,
662
- { getConstantIntExpr (1 )} )
677
+ .callBuiltin (" __builtin_hlsl_buffer_update_counter" , PH::Handle,
678
+ getConstantIntExpr (1 ))
663
679
.finalizeMethod ();
664
680
}
665
681
666
682
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDecrementCounterMethod () {
683
+ using PH = BuiltinTypeMethodBuilder::PlaceHolder;
667
684
return BuiltinTypeMethodBuilder (SemaRef, *this , " DecrementCounter" ,
668
685
SemaRef.getASTContext ().UnsignedIntTy )
669
- .callBuiltin (" __builtin_hlsl_buffer_update_counter" ,
670
- { getConstantIntExpr (-1 )} )
686
+ .callBuiltin (" __builtin_hlsl_buffer_update_counter" , PH::Handle,
687
+ getConstantIntExpr (-1 ))
671
688
.finalizeMethod ();
672
689
}
673
690
0 commit comments