File tree Expand file tree Collapse file tree 3 files changed +51
-1
lines changed Expand file tree Collapse file tree 3 files changed +51
-1
lines changed Original file line number Diff line number Diff line change @@ -462,6 +462,14 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
462
462
TraverseStmt (S->getRangeInit ()) && TraverseStmt (S->getBody ());
463
463
});
464
464
}
465
+ // OpaqueValueExpr blocks traversal, we must explicitly traverse it.
466
+ bool TraverseOpaqueValueExpr (OpaqueValueExpr *E) {
467
+ return traverseNode (E, [&] { return TraverseStmt (E->getSourceExpr ()); });
468
+ }
469
+ // We only want to traverse the *syntactic form* to understand the selection.
470
+ bool TraversePseudoObjectExpr (PseudoObjectExpr *E) {
471
+ return traverseNode (E, [&] { return TraverseStmt (E->getSyntacticForm ()); });
472
+ }
465
473
466
474
private:
467
475
using Base = RecursiveASTVisitor<SelectionVisitor>;
Original file line number Diff line number Diff line change @@ -536,7 +536,8 @@ TEST_F(TargetDeclTest, ObjC) {
536
536
[[f.x]].y = 0;
537
537
}
538
538
)cpp" ;
539
- EXPECT_DECLS (" OpaqueValueExpr" , " @property(atomic, retain, readwrite) I *x" );
539
+ EXPECT_DECLS (" ObjCPropertyRefExpr" ,
540
+ " @property(atomic, retain, readwrite) I *x" );
540
541
541
542
Code = R"cpp(
542
543
@protocol Foo
Original file line number Diff line number Diff line change @@ -323,12 +323,52 @@ TEST(SelectionTest, CommonAncestor) {
323
323
Foo x = [[^12_ud]];
324
324
)cpp" ,
325
325
" UserDefinedLiteral" },
326
+
326
327
{
327
328
R"cpp(
328
329
int a;
329
330
decltype([[^a]] + a) b;
330
331
)cpp" ,
331
332
" DeclRefExpr" },
333
+
334
+ // Objective-C OpaqueValueExpr/PseudoObjectExpr has weird ASTs.
335
+ // Need to traverse the contents of the OpaqueValueExpr to the POE,
336
+ // and ensure we traverse only the syntactic form of the PseudoObjectExpr.
337
+ {
338
+ R"cpp(
339
+ @interface I{}
340
+ @property(retain) I*x;
341
+ @property(retain) I*y;
342
+ @end
343
+ void test(I *f) { [[^f]].x.y = 0; }
344
+ )cpp" ,
345
+ " DeclRefExpr" },
346
+ {
347
+ R"cpp(
348
+ @interface I{}
349
+ @property(retain) I*x;
350
+ @property(retain) I*y;
351
+ @end
352
+ void test(I *f) { [[f.^x]].y = 0; }
353
+ )cpp" ,
354
+ " ObjCPropertyRefExpr" },
355
+ // Examples with implicit properties.
356
+ {
357
+ R"cpp(
358
+ @interface I{}
359
+ -(int)foo;
360
+ @end
361
+ int test(I *f) { return 42 + [[^f]].foo; }
362
+ )cpp" ,
363
+ " DeclRefExpr" },
364
+ {
365
+ R"cpp(
366
+ @interface I{}
367
+ -(int)foo;
368
+ @end
369
+ int test(I *f) { return 42 + [[f.^foo]]; }
370
+ )cpp" ,
371
+ " ObjCPropertyRefExpr" },
332
372
};
333
373
for (const Case &C : Cases) {
334
374
Annotations Test (C.Code );
@@ -339,6 +379,7 @@ TEST(SelectionTest, CommonAncestor) {
339
379
// FIXME: Auto-completion in a template requires disabling delayed template
340
380
// parsing.
341
381
TU.ExtraArgs .push_back (" -fno-delayed-template-parsing" );
382
+ TU.ExtraArgs .push_back (" -xobjective-c++" );
342
383
343
384
auto AST = TU.build ();
344
385
auto T = makeSelectionTree (C.Code , AST);
You can’t perform that action at this time.
0 commit comments