@@ -195,6 +195,81 @@ T buzz(int X, T Y) {
195195 return X + Y;
196196}
197197
198+ // Case 4: Verify that the parameter modifier attributes are instantiated
199+ // for both templated and non-templated arguments, and that the non-templated
200+ // out argument type is not modified by the template instantiation.
201+
202+ // CHECK-LABEL: FunctionTemplateDecl {{.*}} fizz_two
203+
204+ // Check the pattern decl.
205+ // CHECK: FunctionDecl {{.*}} fizz_two 'void (inout T, out int)'
206+ // CHECK-NEXT: ParmVarDecl {{.*}} referenced V 'T'
207+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
208+ // CHECK-NEXT: ParmVarDecl {{.*}} referenced I 'int &__restrict'
209+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
210+
211+ // Check the 3 instantiations (int, float, & double).
212+
213+ // CHECK-LABEL: FunctionDecl {{.*}} used fizz_two 'void (inout int, out int)' implicit_instantiation
214+ // CHECK: ParmVarDecl {{.*}} used V 'int &__restrict'
215+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
216+ // CHECK: ParmVarDecl {{.*}} used I 'int &__restrict'
217+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
218+
219+ // CHECK-LABEL: FunctionDecl {{.*}} used fizz_two 'void (inout float, out int)' implicit_instantiation
220+ // CHECK: ParmVarDecl {{.*}} used V 'float &__restrict'
221+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
222+ // CHECK: ParmVarDecl {{.*}} used I 'int &__restrict'
223+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
224+
225+ // CHECK-LABEL: FunctionDecl {{.*}} used fizz_two 'void (inout double, out int)' implicit_instantiation
226+ // CHECK: ParmVarDecl {{.*}} used V 'double &__restrict'
227+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
228+ // CHECK: ParmVarDecl {{.*}} used I 'int &__restrict'
229+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
230+ template <typename T>
231+ void fizz_two (inout T V, out int I) {
232+ V += 2 ;
233+ I = V;
234+ }
235+
236+ // Case 5: Verify that `in` parameter modifier attributes are instantiated
237+ // for both templated and non-templated arguments and argument types are not
238+ // modified
239+
240+ // CHECK-LABEL: FunctionTemplateDecl {{.*}} buzz_two
241+
242+ // Check the pattern decl.
243+ // CHECK: FunctionDecl {{.*}} buzz_two 'int (T, int)'
244+ // CHECK-NEXT: ParmVarDecl {{.*}} referenced A 'T'
245+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
246+ // CHECK-NEXT: ParmVarDecl {{.*}} referenced B 'int'
247+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
248+
249+ // Check the 3 instantiations (int, float, & double).
250+
251+ // CHECK-LABEL: FunctionDecl {{.*}} used buzz_two 'int (int, int)' implicit_instantiation
252+ // CHECK: ParmVarDecl {{.*}} used A 'int'
253+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
254+ // CHECK: ParmVarDecl {{.*}} used B 'int'
255+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
256+
257+ // CHECK-LABEL: FunctionDecl {{.*}} used buzz_two 'int (float, int)' implicit_instantiation
258+ // CHECK: ParmVarDecl {{.*}} used A 'float'
259+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
260+ // CHECK: ParmVarDecl {{.*}} used B 'int'
261+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
262+
263+ // CHECK-LABEL: FunctionDecl {{.*}} used buzz_two 'int (double, int)' implicit_instantiation
264+ // CHECK: ParmVarDecl {{.*}} used A 'double'
265+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
266+ // CHECK: ParmVarDecl {{.*}} used B 'int'
267+ // CHECK-NEXT: HLSLParamModifierAttr {{.*}} in
268+ template <typename T>
269+ int buzz_two (in T A, in int B) {
270+ return A + B;
271+ }
272+
198273export void caller () {
199274 int X = 2 ;
200275 float Y = 3.3 ;
@@ -211,4 +286,12 @@ export void caller() {
211286 X = buzz (X, X);
212287 Y = buzz (X, Y);
213288 Z = buzz (X, Z);
289+
290+ fizz_two (X, X);
291+ fizz_two (Y, X);
292+ fizz_two (Z, X);
293+
294+ X = buzz_two (X, X);
295+ X = buzz_two (Y, X);
296+ X = buzz_two (Z, X);
214297}
0 commit comments