================ @@ -343,27 +336,224 @@ struct TemplateParameterListBuilder { Params.clear(); QualType T = Builder.Template->getInjectedClassNameSpecialization(); - T = S.Context.getInjectedClassNameType(Builder.Record, T); + T = AST.getInjectedClassNameType(Builder.Record, T); return Builder; } }; + +// Builder for methods of builtin types. Allows adding methods to builtin types +// using the builder pattern like this: +// +// BuiltinTypeMethodBuilder(Sema, RecordBuilder, "MethodName", ReturnType) +// .addParam("param_name", Type, InOutModifier) +// .callBuiltin("buildin_name", { BuiltinParams }) +// .finalizeMethod(); +// +// The builder needs to have all of the method parameters before it can create +// a CXXMethodDecl. It collects them in addParam calls and when a first +// method that builds the body is called it creates the CXXMethodDecl and +// ParmVarDecls instances. These can then be referenced from the body building +// methods. Destructor or an explicit call to finalizeMethod() will complete +// the method definition. ---------------- hekota wrote:
I am trying to keep the same builder pattern for the interface as we already have in the `BuiltinTypeDeclBuilder`. I did have more than just one use case in mind I designed it, but at this moment I can only add building methods that can be tested as part of task llvm/llvm-project#113513. We are going to add more building methods as needed as we implement the rest of the HLSL methods. For example this is how the `Append(T value)` method on the `AppendStructuredBuffer` would look like: ``` BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addIncrementCounterMethod() { ASTContext &AST = S.getASTContext(); Expr *One = IntegerLiteral::Create(...); return BuiltinTypeMethodBuilder(S, *this, "Append", AST.VoidTy) .addParam("value", getFirstTemplateTypeParam()) .callBuiltin("__builtin_hlsl_buffer_update_counter", {One}) .callBuiltinForwardParams("__builtin_hlsl_buffer_load") .finalizeMethod(); } ``` The `callBuiltinForwardParams` passes in the resource handle as the first argument of the builtin (unless that is not desired and the method takes a bool to disable that) and then it adds/forwards all of the Append method params to the builtin call (in this the case the `value`). I believe `callBuiltinForwardParams` will probably be the most commonly used case when we implement other HLSL methods. Without the implicit behavior it might look like this: ``` BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addAppendMethod() { ASTContext &AST = S.getASTContext(); Expr *One = IntegerLiteral::Create(...); BuiltinTypeMethodBuilder MB = BuiltinTypeMethodBuilder(S, *this, "Append", AST.UnsignedIntTy); return MB .addParam("value", getFirstTemplateTypeParam()) .addStmt(callBuiltin(S, "__builtin_hlsl_buffer_update_counter", {MB.getResourceHandleExpr(), One})) .returnExpr(callBuiltin(S, "__builtin_hlsl_buffer_load", {MB.getResourceHandleExpr(), MB.getMethodArg(0)})) } ``` I think the first case looks much simpler. As long as the implicit behavior is well documented and used often enough, I would prefer to keep it like that. I will add more comments pointing out the implicit behavior. https://github.com/llvm/llvm-project/pull/114148 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits