1*89fb8490SChris B// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -finclude-default-header %s -ast-dump | FileCheck %s 2*89fb8490SChris B 3*89fb8490SChris B// Case 1: Template declaration with a call to an inout or out argument that is 4*89fb8490SChris B// resolved based on the template parameter. For this case the template decl 5*89fb8490SChris B// should have an UnresolvedLookupExpr for the call, and the HLSLOutArgExpr is 6*89fb8490SChris B// built during call resolution. 7*89fb8490SChris B 8*89fb8490SChris B// CHECK: FunctionDecl {{.*}} used fn 'void (inout int)' 9*89fb8490SChris Bvoid fn(inout int I) { 10*89fb8490SChris B I += 1; 11*89fb8490SChris B} 12*89fb8490SChris B 13*89fb8490SChris B// CHECK: FunctionDecl {{.*}} used fn 'void (out double)' 14*89fb8490SChris Bvoid fn(out double F) { 15*89fb8490SChris B F = 1.5; 16*89fb8490SChris B} 17*89fb8490SChris B 18*89fb8490SChris B// CHECK-LABEL: FunctionTemplateDecl {{.*}} wrapper 19*89fb8490SChris B// CHECK-NEXT: TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T 20*89fb8490SChris B 21*89fb8490SChris B// Verify that the template has an unresolved call. 22*89fb8490SChris B// CHECK-NEXT: FunctionDecl {{.*}} wrapper 'T (T)' 23*89fb8490SChris B// CHECK-NEXT: ParmVarDecl {{.*}} referenced V 'T' 24*89fb8490SChris B// CHECK: CallExpr {{.*}} '<dependent type>' 25*89fb8490SChris B// CHECK: UnresolvedLookupExpr {{.*}} '<overloaded function type>' lvalue (ADL) = 'fn' 26*89fb8490SChris B 27*89fb8490SChris B// Verify that the int instantiation resolves an inout argument expression. 28*89fb8490SChris B 29*89fb8490SChris B// CHECK-LABEL: FunctionDecl {{.*}} used wrapper 'int (int)' implicit_instantiation 30*89fb8490SChris B// CHECK: CallExpr {{.*}} 'void' 31*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout int)' <FunctionToPointerDecay> 32*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'void (inout int)' lvalue Function {{.*}} 'fn' 'void (inout int)' 33*89fb8490SChris B// CHECK-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout 34*89fb8490SChris B 35*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue 36*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'V' 'int' 37*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue 38*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 39*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue 40*89fb8490SChris B 41*89fb8490SChris B// CHECK: BinaryOperator {{.*}} 'int' lvalue '=' 42*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue 43*89fb8490SChris B// CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 44*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'int' lvalue 45*89fb8490SChris B 46*89fb8490SChris B 47*89fb8490SChris B// Verify that the float instantiation has an out argument expression 48*89fb8490SChris B// containing casts to and from double. 49*89fb8490SChris B 50*89fb8490SChris B// CHECK-LABEL: FunctionDecl {{.*}} used wrapper 'float (float)' implicit_instantiation 51*89fb8490SChris B// CHECK: CallExpr {{.*}} 'void' 52*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(out double)' <FunctionToPointerDecay> 53*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}}'void (out double)' lvalue Function {{.*}} 'fn' 'void (out double)' 54*89fb8490SChris B// CHECK-NEXT: HLSLOutArgExpr {{.*}} 'double' lvalue out 55*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'float' lvalue 56*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'V' 'float' 57*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'double' lvalue 58*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'double' <FloatingCast> 59*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <LValueToRValue> 60*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'float' lvalue 61*89fb8490SChris B 62*89fb8490SChris B// CHECK: BinaryOperator {{.*}} 'float' lvalue '=' 63*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'float' lvalue 64*89fb8490SChris B// CHECK: ImplicitCastExpr {{.*}} 'float' <FloatingCast> 65*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'double' <LValueToRValue> 66*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'double' lvalue 67*89fb8490SChris B 68*89fb8490SChris B 69*89fb8490SChris B// Verify that the double instantiation is just an out expression. 70*89fb8490SChris B 71*89fb8490SChris B// CHECK-LABEL: FunctionDecl {{.*}} used wrapper 'double (double)' implicit_instantiation 72*89fb8490SChris B// CHECK: CallExpr {{.*}} 'void' 73*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(out double)' <FunctionToPointerDecay> 74*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}}'void (out double)' lvalue Function {{.*}} 'fn' 'void (out double)' 75*89fb8490SChris B// CHECK-NEXT: HLSLOutArgExpr {{.*}} 'double' lvalue out 76*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'double' lvalue 77*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'double' lvalue ParmVar {{.*}} 'V' 'double' 78*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'double' lvalue 79*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'double' <LValueToRValue> 80*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'double' lvalue 81*89fb8490SChris B 82*89fb8490SChris B// CHECK: BinaryOperator {{.*}} 'double' lvalue '=' 83*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'double' lvalue 84*89fb8490SChris B// CHECK: ImplicitCastExpr {{.*}} 'double' <LValueToRValue> 85*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'double' lvalue 86*89fb8490SChris B 87*89fb8490SChris Btemplate <typename T> 88*89fb8490SChris BT wrapper(T V) { 89*89fb8490SChris B fn(V); 90*89fb8490SChris B return V; 91*89fb8490SChris B} 92*89fb8490SChris B 93*89fb8490SChris B// Case 2: Verify that the parameter modifier attribute is instantiated with the 94*89fb8490SChris B// template (this one is a gimme). 95*89fb8490SChris B 96*89fb8490SChris B// CHECK-LABEL: FunctionTemplateDecl {{.*}} fizz 97*89fb8490SChris B 98*89fb8490SChris B// Check the pattern decl. 99*89fb8490SChris B// CHECK: FunctionDecl {{.*}} fizz 'void (inout T)' 100*89fb8490SChris B// CHECK-NEXT: ParmVarDecl {{.*}} referenced V 'T' 101*89fb8490SChris B// CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout 102*89fb8490SChris B 103*89fb8490SChris B// Check the 3 instantiations (int, float, & double). 104*89fb8490SChris B 105*89fb8490SChris B// CHECK-LABEL: FunctionDecl {{.*}} used fizz 'void (inout int)' implicit_instantiation 106*89fb8490SChris B// CHECK: ParmVarDecl {{.*}} used V 'int &__restrict' 107*89fb8490SChris B// CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout 108*89fb8490SChris B 109*89fb8490SChris B// CHECK-LABEL: FunctionDecl {{.*}} used fizz 'void (inout float)' implicit_instantiation 110*89fb8490SChris B// CHECK: ParmVarDecl {{.*}} used V 'float &__restrict' 111*89fb8490SChris B// CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout 112*89fb8490SChris B 113*89fb8490SChris B// CHECK-LABEL: FunctionDecl {{.*}} used fizz 'void (inout double)' implicit_instantiation 114*89fb8490SChris B// CHECK: ParmVarDecl {{.*}} used V 'double &__restrict' 115*89fb8490SChris B// CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout 116*89fb8490SChris Btemplate <typename T> 117*89fb8490SChris Bvoid fizz(inout T V) { 118*89fb8490SChris B V += 2; 119*89fb8490SChris B} 120*89fb8490SChris B 121*89fb8490SChris B// Case 3: Verify that HLSLOutArgExpr nodes which are present in the template 122*89fb8490SChris B// are correctly instantiated into the instantation. 123*89fb8490SChris B 124*89fb8490SChris B// First we check that the AST node is in the template. 125*89fb8490SChris B 126*89fb8490SChris B// CHECK-LABEL: FunctionTemplateDecl {{.*}} buzz 127*89fb8490SChris B 128*89fb8490SChris B// CHECK: FunctionDecl {{.*}} buzz 'T (int, T)' 129*89fb8490SChris B// CHECK: CallExpr {{.*}} 'void' 130*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout int)' <FunctionToPointerDecay> 131*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'void (inout int)' lvalue Function {{.*}} 'fn' 'void (inout int)' 132*89fb8490SChris B// CHECK-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout 133*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue 134*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'X' 'int' 135*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue 136*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 137*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue 138*89fb8490SChris B// CHECK: BinaryOperator {{.*}} 'int' lvalue '=' 139*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue 140*89fb8490SChris B// CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 141*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'int' lvalue 142*89fb8490SChris B 143*89fb8490SChris B 144*89fb8490SChris B 145*89fb8490SChris B// CHECK-LABEL: FunctionDecl {{.*}} used buzz 'int (int, int)' implicit_instantiation 146*89fb8490SChris B// CHECK: CallExpr {{.*}} 'void' 147*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout int)' <FunctionToPointerDecay> 148*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'void (inout int)' lvalue Function {{.*}} 'fn' 'void (inout int)' 149*89fb8490SChris B// CHECK-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout 150*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue 151*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'X' 'int' 152*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue 153*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 154*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue 155*89fb8490SChris B// CHECK: BinaryOperator {{.*}} 'int' lvalue '=' 156*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue 157*89fb8490SChris B// CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 158*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'int' lvalue 159*89fb8490SChris B 160*89fb8490SChris B 161*89fb8490SChris B// CHECK-LABEL: FunctionDecl {{.*}} used buzz 'float (int, float)' implicit_instantiation 162*89fb8490SChris B// CHECK: CallExpr {{.*}} 'void' 163*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout int)' <FunctionToPointerDecay> 164*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'void (inout int)' lvalue Function {{.*}} 'fn' 'void (inout int)' 165*89fb8490SChris B// CHECK-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout 166*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue 167*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'X' 'int' 168*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue 169*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 170*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue 171*89fb8490SChris B// CHECK: BinaryOperator {{.*}} 'int' lvalue '=' 172*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue 173*89fb8490SChris B// CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 174*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'int' lvalue 175*89fb8490SChris B 176*89fb8490SChris B 177*89fb8490SChris B// CHECK-LABEL: FunctionDecl {{.*}} used buzz 'double (int, double)' implicit_instantiation 178*89fb8490SChris B// CHECK: CallExpr {{.*}} 'void' 179*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout int)' <FunctionToPointerDecay> 180*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'void (inout int)' lvalue Function {{.*}} 'fn' 'void (inout int)' 181*89fb8490SChris B// CHECK-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout 182*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue 183*89fb8490SChris B// CHECK-NEXT: DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'X' 'int' 184*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue 185*89fb8490SChris B// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 186*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue 187*89fb8490SChris B// CHECK: BinaryOperator {{.*}} 'int' lvalue '=' 188*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'int' lvalue 189*89fb8490SChris B// CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> 190*89fb8490SChris B// CHECK-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'int' lvalue 191*89fb8490SChris B 192*89fb8490SChris Btemplate <typename T> 193*89fb8490SChris BT buzz(int X, T Y) { 194*89fb8490SChris B fn(X); 195*89fb8490SChris B return X + Y; 196*89fb8490SChris B} 197*89fb8490SChris B 198*89fb8490SChris Bexport void caller() { 199*89fb8490SChris B int X = 2; 200*89fb8490SChris B float Y = 3.3; 201*89fb8490SChris B double Z = 2.2; 202*89fb8490SChris B 203*89fb8490SChris B X = wrapper(X); 204*89fb8490SChris B Y = wrapper(Y); 205*89fb8490SChris B Z = wrapper(Z); 206*89fb8490SChris B 207*89fb8490SChris B fizz(X); 208*89fb8490SChris B fizz(Y); 209*89fb8490SChris B fizz(Z); 210*89fb8490SChris B 211*89fb8490SChris B X = buzz(X, X); 212*89fb8490SChris B Y = buzz(X, Y); 213*89fb8490SChris B Z = buzz(X, Z); 214*89fb8490SChris B} 215