1 // RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -std=gnu++17 -frecovery-ast -frecovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
2 // RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -std=gnu++17 -fno-recovery-ast -ast-dump %s | FileCheck --check-prefix=DISABLED -strict-whitespace %s
3 
4 int some_func(int *);
5 
6 // CHECK:     VarDecl {{.*}} invalid_call
7 // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'int' contains-errors
8 // CHECK-NEXT:    |-UnresolvedLookupExpr {{.*}} 'some_func'
9 // CHECK-NEXT:    `-IntegerLiteral {{.*}} 123
10 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
11 int invalid_call = some_func(123);
test_invalid_call(int s)12 void test_invalid_call(int s) {
13   // CHECK:      CallExpr {{.*}} '<dependent type>' contains-errors
14   // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func'
15   // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:13>
16   // CHECK-NEXT: `-BinaryOperator {{.*}}
17   // CHECK-NEXT:   |-RecoveryExpr {{.*}}
18   // CHECK-NEXT:   `-IntegerLiteral {{.*}} <col:28> 'int' 1
19   some_func(undef1, undef2+1);
20 
21   // CHECK:      BinaryOperator {{.*}} '<dependent type>' contains-errors '='
22   // CHECK-NEXT: |-DeclRefExpr {{.*}} 's'
23   // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
24   // CHECK-NEXT:   |-UnresolvedLookupExpr {{.*}} 'some_func'
25   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
26   s = some_func(undef1);
27 
28   // CHECK:     VarDecl {{.*}} var 'int'
29   // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
30   // CHECK-NEXT:   |-UnresolvedLookupExpr {{.*}} 'some_func'
31   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
32   int var = some_func(undef1);
33 }
34 
35 int ambig_func(double);
36 int ambig_func(float);
37 
38 // CHECK:     VarDecl {{.*}} ambig_call
39 // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'int' contains-errors
40 // CHECK-NEXT:    |-UnresolvedLookupExpr {{.*}} 'ambig_func'
41 // CHECK-NEXT:    `-IntegerLiteral {{.*}} 123
42 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
43 int ambig_call = ambig_func(123);
44 
45 // CHECK:     VarDecl {{.*}} unresolved_call1
46 // CHECK-NEXT:`-RecoveryExpr {{.*}} '<dependent type>' contains-errors
47 // CHECK-NEXT:  `-UnresolvedLookupExpr {{.*}} 'bar'
48 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
49 int unresolved_call1 = bar();
50 
51 // CHECK:     VarDecl {{.*}} unresolved_call2
52 // CHECK-NEXT:`-CallExpr {{.*}} contains-errors
53 // CHECK-NEXT:  |-UnresolvedLookupExpr {{.*}} 'bar'
54 // CHECK-NEXT:  |-RecoveryExpr {{.*}} contains-errors
55 // CHECK-NEXT:  | `-UnresolvedLookupExpr {{.*}} 'baz'
56 // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
57 // CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'qux'
58 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
59 int unresolved_call2 = bar(baz(), qux());
60 
61 constexpr int a = 10;
62 
63 // CHECK:     VarDecl {{.*}} postfix_inc
64 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
65 // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a'
66 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
67 int postfix_inc = a++;
68 
69 // CHECK:     VarDecl {{.*}} prefix_inc
70 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
71 // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a'
72 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
73 int prefix_inc = ++a;
74 
75 // CHECK:     VarDecl {{.*}} unary_address
76 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
77 // CHECK-NEXT:  `-ParenExpr {{.*}}
78 // CHECK-NEXT:    `-BinaryOperator {{.*}} '+'
79 // CHECK-NEXT:      |-ImplicitCastExpr
80 // CHECK-NEXT:      | `-DeclRefExpr {{.*}} 'a'
81 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
82 int unary_address = &(a + 1);
83 
84 // CHECK:     VarDecl {{.*}} unary_bitinverse
85 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
86 // CHECK-NEXT:  `-ParenExpr {{.*}}
87 // CHECK-NEXT:    `-BinaryOperator {{.*}} '+'
88 // CHECK-NEXT:      |-ImplicitCastExpr
89 // CHECK-NEXT:      | `-ImplicitCastExpr
90 // CHECK-NEXT:      |   `-DeclRefExpr {{.*}} 'a'
91 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
92 int unary_bitinverse = ~(a + 0.0);
93 
94 // CHECK:     VarDecl {{.*}} binary
95 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
96 // CHECK-NEXT:  |-DeclRefExpr {{.*}} 'a'
97 // CHECK-NEXT:  `-CXXNullPtrLiteralExpr
98 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
99 int binary = a + nullptr;
100 
101 // CHECK:     VarDecl {{.*}} ternary
102 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
103 // CHECK-NEXT:  |-DeclRefExpr {{.*}} 'a'
104 // CHECK-NEXT:  |-CXXNullPtrLiteralExpr
105 // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a'
106 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
107 int ternary = a ? nullptr : a;
108 
109 // CHECK:     FunctionDecl
110 // CHECK-NEXT:|-ParmVarDecl {{.*}} x
111 // CHECK-NEXT:`-CompoundStmt
112 // CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors
113 // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'foo'
114 // CHECK-NEXT: `-CallExpr {{.*}} contains-errors
115 // CHECK-NEXT:  |-RecoveryExpr {{.*}} contains-errors
116 // CHECK-NEXT:  | `-DeclRefExpr {{.*}} 'foo'
117 // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'x'
118 struct Foo {} foo;
test(int x)119 void test(int x) {
120   foo.abc;
121   foo->func(x);
122 }
123 
AccessIncompleteClass()124 void AccessIncompleteClass() {
125   struct Forward;
126   Forward* ptr;
127   // CHECK:      CallExpr {{.*}} '<dependent type>'
128   // CHECK-NEXT: `-CXXDependentScopeMemberExpr {{.*}} '<dependent type>'
129   // CHECK-NEXT:   `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
130   // CHECK-NEXT:     `-DeclRefExpr {{.*}} 'Forward *'
131   ptr->method();
132 }
133 
134 struct Foo2 {
135   double func();
136   class ForwardClass;
137   ForwardClass createFwd();
138 
139   int overload();
140   int overload(int, int);
141 };
test2(Foo2 f)142 void test2(Foo2 f) {
143   // CHECK:      RecoveryExpr {{.*}} 'double'
144   // CHECK-NEXT:   |-MemberExpr {{.*}} '<bound member function type>'
145   // CHECK-NEXT:   | `-DeclRefExpr {{.*}} 'f'
146   // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
147   f.func(1);
148   // CHECK:      RecoveryExpr {{.*}} 'Foo2::ForwardClass'
149   // CHECK-NEXT: `-MemberExpr {{.*}} '<bound member function type>' .createFwd
150   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'f'
151   f.createFwd();
152   // CHECK:      RecoveryExpr {{.*}} 'int' contains-errors
153   // CHECK-NEXT: |-UnresolvedMemberExpr
154   // CHECK-NEXT:    `-DeclRefExpr {{.*}} 'Foo2'
155   // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
156   f.overload(1);
157 }
158 
159 // CHECK:     |-AlignedAttr {{.*}} alignas
160 // CHECK-NEXT:| `-RecoveryExpr {{.*}} contains-errors
161 // CHECK-NEXT:|   `-UnresolvedLookupExpr {{.*}} 'invalid'
162 struct alignas(invalid()) Aligned {};
163 
164 auto f();
165 int f(double);
166 // CHECK:      VarDecl {{.*}} unknown_type_call 'int'
167 // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
168 int unknown_type_call = f(0, 0);
169 
InvalidInitalizer(int x)170 void InvalidInitalizer(int x) {
171   struct Bar { Bar(); };
172   // CHECK:     `-VarDecl {{.*}} a1 'Bar'
173   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
174   // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
175   Bar a1(1);
176   // CHECK:     `-VarDecl {{.*}} a2 'Bar'
177   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
178   // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'x'
179   Bar a2(x);
180   // CHECK:     `-VarDecl {{.*}} a3 'Bar'
181   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
182   // CHECK-NEXT:  `-InitListExpr
183   // CHECK-NEDT:   `-DeclRefExpr {{.*}} 'x'
184   Bar a3{x};
185   // CHECK:     `-VarDecl {{.*}} a4 'Bar'
186   // CHECK-NEXT: `-ParenListExpr {{.*}} 'NULL TYPE' contains-errors
187   // CHECK-NEXT:  `-RecoveryExpr {{.*}} contains-errors
188   // CHECK-NEXT:   `-UnresolvedLookupExpr {{.*}} 'invalid'
189   Bar a4(invalid());
190   // CHECK:     `-VarDecl {{.*}} a5 'Bar'
191   // CHECK-NEXT: `-InitListExpr {{.*}} contains-errors
192   // CHECK-NEXT:  `-RecoveryExpr {{.*}} contains-errors
193   // CHECK-NEXT:   `-UnresolvedLookupExpr {{.*}} 'invalid'
194   Bar a5{invalid()};
195 
196   // CHECK:     `-VarDecl {{.*}} b1 'Bar'
197   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
198   // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
199   Bar b1 = 1;
200   // CHECK:     `-VarDecl {{.*}} b2 'Bar'
201   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
202   // CHECK-NEXT:  `-InitListExpr
203   Bar b2 = {1};
204   // CHECK:     `-VarDecl {{.*}} b3 'Bar'
205   // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
206   // CHECK-NEXT:    `-DeclRefExpr {{.*}} 'x' 'int'
207   Bar b3 = Bar(x);
208   // CHECK:     `-VarDecl {{.*}} b4 'Bar'
209   // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
210   // CHECK-NEXT:    `-InitListExpr {{.*}} 'void'
211   // CHECK-NEXT:      `-DeclRefExpr {{.*}} 'x' 'int'
212   Bar b4 = Bar{x};
213   // CHECK:     `-VarDecl {{.*}} b5 'Bar'
214   // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 'Bar'
215   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
216   // CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'invalid'
217   Bar b5 = Bar(invalid());
218   // CHECK:     `-VarDecl {{.*}} b6 'Bar'
219   // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 'Bar'
220   // CHECK-NEXT:  `-InitListExpr {{.*}} contains-errors
221   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
222   // CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'invalid'
223   Bar b6 = Bar{invalid()};
224 
225   // CHECK:     RecoveryExpr {{.*}} 'Bar' contains-errors
226   // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
227   Bar(1);
228 
229   // CHECK:     `-VarDecl {{.*}} var1
230   // CHECK-NEXT: `-BinaryOperator {{.*}} '<dependent type>' contains-errors
231   // CHECK-NEXT:   |-RecoveryExpr {{.*}} '<dependent type>' contains-errors
232   // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 1
233   int var1 = undef + 1;
234 }
InitializerForAuto()235 void InitializerForAuto() {
236   // CHECK:     `-VarDecl {{.*}} invalid a 'auto'
237   // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
238   // CHECK-NEXT:   `-UnresolvedLookupExpr {{.*}} 'invalid'
239   auto a = invalid();
240 
241   // CHECK:     `-VarDecl {{.*}} invalid b 'auto'
242   // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
243   // CHECK-NEXT:   |-UnresolvedLookupExpr {{.*}} 'some_func'
244   // CHECK-NEXT:   `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
245   // CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'invalid'
246   auto b = some_func(invalid());
247 
248   decltype(ned);
249   // very bad initailizer: there is an unresolved typo expr internally, we just
250   // drop it.
251   // CHECK: `-VarDecl {{.*}} invalid unresolved_typo 'auto'
252   auto unresolved_typo = gned.*[] {};
253 }
254 
255 // Verified that the generated call operator is invalid.
256 // CHECK: |-CXXMethodDecl {{.*}} invalid operator() 'auto () const -> auto'
__anonb5846cf10202null257 using Escape = decltype([] { return undef(); }());
258 
259 // CHECK:      VarDecl {{.*}} NoCrashOnInvalidInitList
260 // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors lvalue
261 // CHECK-NEXT:   `-InitListExpr
262 // CHECK-NEXT:     `-DesignatedInitExpr {{.*}} 'void'
263 // CHECK-NEXT:       `-CXXNullPtrLiteralExpr {{.*}} 'std::nullptr_t'
264 struct {
265   int& abc;
266 } NoCrashOnInvalidInitList = {
267   .abc = nullptr,
268 };
269 
270 // Verify the value category of recovery expression.
271 int prvalue(int);
272 int &lvalue(int);
273 int &&xvalue(int);
ValueCategory()274 void ValueCategory() {
275   // CHECK:  RecoveryExpr {{.*}} 'int' contains-errors
276   prvalue(); // call to a function (nonreference return type) yields a prvalue (not print by default)
277   // CHECK:  RecoveryExpr {{.*}} 'int' contains-errors lvalue
278   lvalue(); // call to a function (lvalue reference return type) yields an lvalue.
279   // CHECK:  RecoveryExpr {{.*}} 'int' contains-errors xvalue
280   xvalue(); // call to a function (rvalue reference return type) yields an xvalue.
281 }
282 
InvalidCondition()283 void InvalidCondition() {
284   // CHECK:      IfStmt {{.*}}
285   // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:7, col:15> '<dependent type>' contains-errors
286   // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:7>
287   if (invalid()) {}
288 
289   // CHECK:      WhileStmt {{.*}}
290   // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:10, col:18> '<dependent type>' contains-errors
291   // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10>
292   while (invalid()) {}
293 
294   // CHECK:      SwitchStmt {{.*}}
295   // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors
296   // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10>
297   switch(invalid()) {
298     case 1:
299       break;
300   }
301   // FIXME: figure out why the type of ConditionalOperator is not int.
302   // CHECK:      ConditionalOperator {{.*}} '<dependent type>' contains-errors
303   // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors
304   // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}}
305   // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1
306   // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2
307   invalid() ? 1 : 2;
308 }
309 
CtorInitializer()310 void CtorInitializer() {
311   struct S{int m};
312   class MemberInit {
313     int x, y, z;
314     S s;
315     MemberInit() : x(invalid), y(invalid, invalid), z(invalid()), s(1,2) {}
316     // CHECK:      CXXConstructorDecl {{.*}} MemberInit 'void ()'
317     // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'x' 'int'
318     // CHECK-NEXT: | `-ParenListExpr
319     // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
320     // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'y' 'int'
321     // CHECK-NEXT: | `-ParenListExpr
322     // CHECK-NEXT: |   |-RecoveryExpr {{.*}} '<dependent type>'
323     // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
324     // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'z' 'int'
325     // CHECK-NEXT: | `-ParenListExpr
326     // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
327     // CHECK-NEXT: |     `-UnresolvedLookupExpr {{.*}} '<overloaded function type>'
328     // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 's' 'S'
329     // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'S' contains-errors
330     // CHECK-NEXT: |   |-IntegerLiteral {{.*}} 1
331     // CHECK-NEXT: |   `-IntegerLiteral {{.*}} 2
332   };
333   class BaseInit : S {
334     BaseInit(float) : S("no match") {}
335     // CHECK:      CXXConstructorDecl {{.*}} BaseInit 'void (float)'
336     // CHECK-NEXT: |-ParmVarDecl
337     // CHECK-NEXT: |-CXXCtorInitializer 'S'
338     // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'S'
339     // CHECK-NEXT: |   `-StringLiteral
340 
341     BaseInit(double) : S(invalid) {}
342     // CHECK:      CXXConstructorDecl {{.*}} BaseInit 'void (double)'
343     // CHECK-NEXT: |-ParmVarDecl
344     // CHECK-NEXT: |-CXXCtorInitializer 'S'
345     // CHECK-NEXT: | `-ParenListExpr
346     // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
347   };
348   class DelegatingInit {
349     DelegatingInit(float) : DelegatingInit("no match") {}
350     // CHECK:      CXXConstructorDecl {{.*}} DelegatingInit 'void (float)'
351     // CHECK-NEXT: |-ParmVarDecl
352     // CHECK-NEXT: |-CXXCtorInitializer 'DelegatingInit'
353     // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'DelegatingInit'
354     // CHECK-NEXT: |   `-StringLiteral
355 
356     DelegatingInit(double) : DelegatingInit(invalid) {}
357     // CHECK:      CXXConstructorDecl {{.*}} DelegatingInit 'void (double)'
358     // CHECK-NEXT: |-ParmVarDecl
359     // CHECK-NEXT: |-CXXCtorInitializer 'DelegatingInit'
360     // CHECK-NEXT: | `-ParenListExpr
361     // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
362   };
363 }
364 
brokenReturn()365 float *brokenReturn() {
366   // CHECK:      FunctionDecl {{.*}} brokenReturn
367   return 42;
368   // CHECK:      ReturnStmt
369   // CHECK-NEXT: `-RecoveryExpr {{.*}} 'float *'
370   // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 42
371 }
372 
373 // Return deduction treats the first, second *and* third differently!
brokenDeducedReturn(int * x,float * y,double * z)374 auto *brokenDeducedReturn(int *x, float *y, double *z) {
375   // CHECK:      FunctionDecl {{.*}} invalid brokenDeducedReturn
376   if (x) return x;
377   // CHECK:      ReturnStmt
378   // CHECK-NEXT: `-ImplicitCastExpr {{.*}} <LValueToRValue>
379   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'x' 'int *'
380   if (y) return y;
381   // CHECK:      ReturnStmt
382   // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int *'
383   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'y' 'float *'
384   if (z) return z;
385   // CHECK:      ReturnStmt
386   // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int *'
387   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'z' 'double *'
388   return x;
389   // Unfortunate: we wrap a valid return in RecoveryExpr.
390   // This is to avoid running deduction again after it failed once.
391   // CHECK:      ReturnStmt
392   // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int *'
393   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'x' 'int *'
394 }
395 
returnInitListFromVoid()396 void returnInitListFromVoid() {
397   // CHECK:      FunctionDecl {{.*}} returnInitListFromVoid
398   return {7,8};
399   // CHECK:      ReturnStmt
400   // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
401   // CHECK-NEXT:   |-IntegerLiteral {{.*}} 'int' 7
402   // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 8
403 }
404 
RecoveryExprForInvalidDecls(Unknown InvalidDecl)405 void RecoveryExprForInvalidDecls(Unknown InvalidDecl) {
406   InvalidDecl + 1;
407   // CHECK:      BinaryOperator {{.*}}
408   // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>'
409   // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
410   InvalidDecl();
411   // CHECK:      CallExpr {{.*}}
412   // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
413 }
414