1 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -finclude-default-header %s -ast-dump | FileCheck %s
3 // Case 1: Template declaration with a call to an inout or out argument that is
4 // resolved based on the template parameter. For this case the template decl
5 // should have an UnresolvedLookupExpr for the call, and the HLSLOutArgExpr is
6 // built during call resolution.
8 // CHECK: FunctionDecl {{.*}} used fn 'void (inout int)'
13 // CHECK: FunctionDecl {{.*}} used fn 'void (out double)'
14 void fn(out double F) {
18 // CHECK-LABEL: FunctionTemplateDecl {{.*}} wrapper
19 // CHECK-NEXT: TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T
21 // Verify that the template has an unresolved call.
22 // CHECK-NEXT: FunctionDecl {{.*}} wrapper 'T (T)'
23 // CHECK-NEXT: ParmVarDecl {{.*}} referenced V 'T'
24 // CHECK: CallExpr {{.*}} '<dependent type>'
25 // CHECK: UnresolvedLookupExpr {{.*}} '<overloaded function type>' lvalue (ADL) = 'fn'
27 // Verify that the int instantiation resolves an inout argument expression.
29 // CHECK-LABEL: FunctionDecl {{.*}} used wrapper 'int (int)' implicit_instantiation
30 // CHECK: CallExpr {{.*}} 'void'
31 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout int)' <FunctionToPointerDecay>
32 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (inout int)' lvalue Function {{.*}} 'fn' 'void (inout int)'
33 // CHECK-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout
35 // CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue
36 // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'V' 'int'
37 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue
38 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
39 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue
41 // CHECK: BinaryOperator {{.*}} 'int' lvalue '='
42 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue
43 // CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
44 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'int' lvalue
47 // Verify that the float instantiation has an out argument expression
48 // containing casts to and from double.
50 // CHECK-LABEL: FunctionDecl {{.*}} used wrapper 'float (float)' implicit_instantiation
51 // CHECK: CallExpr {{.*}} 'void'
52 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(out double)' <FunctionToPointerDecay>
53 // CHECK-NEXT: DeclRefExpr {{.*}}'void (out double)' lvalue Function {{.*}} 'fn' 'void (out double)'
54 // CHECK-NEXT: HLSLOutArgExpr {{.*}} 'double' lvalue out
55 // CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'float' lvalue
56 // CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'V' 'float'
57 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'double' lvalue
58 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'double' <FloatingCast>
59 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <LValueToRValue>
60 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'float' lvalue
62 // CHECK: BinaryOperator {{.*}} 'float' lvalue '='
63 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'float' lvalue
64 // CHECK: ImplicitCastExpr {{.*}} 'float' <FloatingCast>
65 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'double' <LValueToRValue>
66 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'double' lvalue
69 // Verify that the double instantiation is just an out expression.
71 // CHECK-LABEL: FunctionDecl {{.*}} used wrapper 'double (double)' implicit_instantiation
72 // CHECK: CallExpr {{.*}} 'void'
73 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(out double)' <FunctionToPointerDecay>
74 // CHECK-NEXT: DeclRefExpr {{.*}}'void (out double)' lvalue Function {{.*}} 'fn' 'void (out double)'
75 // CHECK-NEXT: HLSLOutArgExpr {{.*}} 'double' lvalue out
76 // CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'double' lvalue
77 // CHECK-NEXT: DeclRefExpr {{.*}} 'double' lvalue ParmVar {{.*}} 'V' 'double'
78 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'double' lvalue
79 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'double' <LValueToRValue>
80 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'double' lvalue
82 // CHECK: BinaryOperator {{.*}} 'double' lvalue '='
83 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'double' lvalue
84 // CHECK: ImplicitCastExpr {{.*}} 'double' <LValueToRValue>
85 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'double' lvalue
93 // Case 2: Verify that the parameter modifier attribute is instantiated with the
94 // template (this one is a gimme).
96 // CHECK-LABEL: FunctionTemplateDecl {{.*}} fizz
98 // Check the pattern decl.
99 // CHECK: FunctionDecl {{.*}} fizz 'void (inout T)'
100 // CHECK-NEXT: ParmVarDecl {{.*}} referenced V 'T'
101 // CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
103 // Check the 3 instantiations (int, float, & double).
105 // CHECK-LABEL: FunctionDecl {{.*}} used fizz 'void (inout int)' implicit_instantiation
106 // CHECK: ParmVarDecl {{.*}} used V 'int &__restrict'
107 // CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
109 // CHECK-LABEL: FunctionDecl {{.*}} used fizz 'void (inout float)' implicit_instantiation
110 // CHECK: ParmVarDecl {{.*}} used V 'float &__restrict'
111 // CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
113 // CHECK-LABEL: FunctionDecl {{.*}} used fizz 'void (inout double)' implicit_instantiation
114 // CHECK: ParmVarDecl {{.*}} used V 'double &__restrict'
115 // CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout
116 template <typename T>
117 void fizz(inout T V) {
121 // Case 3: Verify that HLSLOutArgExpr nodes which are present in the template
122 // are correctly instantiated into the instantation.
124 // First we check that the AST node is in the template.
126 // CHECK-LABEL: FunctionTemplateDecl {{.*}} buzz
128 // CHECK: FunctionDecl {{.*}} buzz 'T (int, T)'
129 // CHECK: CallExpr {{.*}} 'void'
130 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout int)' <FunctionToPointerDecay>
131 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (inout int)' lvalue Function {{.*}} 'fn' 'void (inout int)'
132 // CHECK-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout
133 // CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue
134 // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'X' 'int'
135 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue
136 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
137 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue
138 // CHECK: BinaryOperator {{.*}} 'int' lvalue '='
139 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue
140 // CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
141 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'int' lvalue
145 // CHECK-LABEL: FunctionDecl {{.*}} used buzz 'int (int, int)' implicit_instantiation
146 // CHECK: CallExpr {{.*}} 'void'
147 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout int)' <FunctionToPointerDecay>
148 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (inout int)' lvalue Function {{.*}} 'fn' 'void (inout int)'
149 // CHECK-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout
150 // CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue
151 // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'X' 'int'
152 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue
153 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
154 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue
155 // CHECK: BinaryOperator {{.*}} 'int' lvalue '='
156 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue
157 // CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
158 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'int' lvalue
161 // CHECK-LABEL: FunctionDecl {{.*}} used buzz 'float (int, float)' implicit_instantiation
162 // CHECK: CallExpr {{.*}} 'void'
163 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout int)' <FunctionToPointerDecay>
164 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (inout int)' lvalue Function {{.*}} 'fn' 'void (inout int)'
165 // CHECK-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout
166 // CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue
167 // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'X' 'int'
168 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue
169 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
170 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue
171 // CHECK: BinaryOperator {{.*}} 'int' lvalue '='
172 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue
173 // CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
174 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'int' lvalue
177 // CHECK-LABEL: FunctionDecl {{.*}} used buzz 'double (int, double)' implicit_instantiation
178 // CHECK: CallExpr {{.*}} 'void'
179 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout int)' <FunctionToPointerDecay>
180 // CHECK-NEXT: DeclRefExpr {{.*}} 'void (inout int)' lvalue Function {{.*}} 'fn' 'void (inout int)'
181 // CHECK-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout
182 // CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue
183 // CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'X' 'int'
184 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue
185 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
186 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue
187 // CHECK: BinaryOperator {{.*}} 'int' lvalue '='
188 // CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue
189 // CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
190 // CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'int' lvalue
192 template <typename T>
198 export void caller() {