diff options
Diffstat (limited to 'clang/unittests/Tooling/ASTSelectionTest.cpp')
-rw-r--r-- | clang/unittests/Tooling/ASTSelectionTest.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/clang/unittests/Tooling/ASTSelectionTest.cpp b/clang/unittests/Tooling/ASTSelectionTest.cpp index bde052e849c..6b76bf06cb5 100644 --- a/clang/unittests/Tooling/ASTSelectionTest.cpp +++ b/clang/unittests/Tooling/ASTSelectionTest.cpp @@ -513,4 +513,140 @@ TEST(ASTSelectionFinder, CorrectEndForObjectiveCImplementation) { SelectionFinderVisitor::Lang_OBJC); } +const SelectedASTNode &checkFnBody(const Optional<SelectedASTNode> &Node, + StringRef Name) { + EXPECT_TRUE(Node); + EXPECT_EQ(Node->Children.size(), 1u); + const auto &Fn = checkNode<FunctionDecl>( + Node->Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1, Name); + return checkNode<CompoundStmt>(Fn.Children[0], + SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); +} + +TEST(ASTSelectionFinder, SelectObjectiveCPseudoObjectExprs) { + StringRef Source = R"( +@interface I +@property(readwrite) int prop; +@end +void selectProp(I *i) { +(void)i.prop; +i.prop = 21; +} + +typedef unsigned int size_t; +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(size_t)index; +- (void)setObject:(id)object atIndexedSubscript:(size_t)index; +@end + +void selectSubscript(NSMutableArray *array, I *i) { + (void)array[10]; + array[i.prop] = i; +} +)"; + // Just 'i.prop'. + findSelectedASTNodes( + Source, {6, 7}, FileRange{{6, 7}, {6, 13}}, + [](Optional<SelectedASTNode> Node) { + const auto &CS = checkFnBody(Node, /*Name=*/"selectProp"); + const auto &CCast = checkNode<CStyleCastExpr>( + CS.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &POE = checkNode<PseudoObjectExpr>( + CCast.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &PRE = checkNode<ObjCPropertyRefExpr>( + POE.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &Cast = checkNode<ImplicitCastExpr>( + PRE.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + checkNode<DeclRefExpr>(Cast.Children[0], + SourceSelectionKind::InsideSelection); + }, + SelectionFinderVisitor::Lang_OBJC); + // Just 'i.prop = 21' + findSelectedASTNodes( + Source, {7, 1}, FileRange{{7, 1}, {7, 12}}, + [](Optional<SelectedASTNode> Node) { + const auto &CS = checkFnBody(Node, /*Name=*/"selectProp"); + const auto &POE = checkNode<PseudoObjectExpr>( + CS.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &BinOp = checkNode<BinaryOperator>( + POE.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/2); + const auto &PRE = checkNode<ObjCPropertyRefExpr>( + BinOp.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + const auto &Cast = checkNode<ImplicitCastExpr>( + PRE.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + checkNode<DeclRefExpr>(Cast.Children[0], + SourceSelectionKind::InsideSelection); + checkNode<IntegerLiteral>(BinOp.Children[1], + SourceSelectionKind::InsideSelection); + }, + SelectionFinderVisitor::Lang_OBJC); + // Just 'array[10]' + findSelectedASTNodes( + Source, {17, 9}, FileRange{{17, 9}, {17, 18}}, + [](Optional<SelectedASTNode> Node) { + const auto &CS = checkFnBody(Node, /*Name=*/"selectSubscript"); + const auto &CCast = checkNode<CStyleCastExpr>( + CS.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &POE = checkNode<PseudoObjectExpr>( + CCast.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &SRE = checkNode<ObjCSubscriptRefExpr>( + POE.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/2); + const auto &Cast = checkNode<ImplicitCastExpr>( + SRE.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + checkNode<DeclRefExpr>(Cast.Children[0], + SourceSelectionKind::InsideSelection); + checkNode<IntegerLiteral>(SRE.Children[1], + SourceSelectionKind::InsideSelection); + }, + SelectionFinderVisitor::Lang_OBJC); + // Just 'array[i.prop] = array' + findSelectedASTNodes( + Source, {18, 3}, FileRange{{18, 3}, {18, 20}}, + [](Optional<SelectedASTNode> Node) { + const auto &CS = checkFnBody(Node, /*Name=*/"selectSubscript"); + const auto &POE = checkNode<PseudoObjectExpr>( + CS.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &BinOp = checkNode<BinaryOperator>( + POE.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/2); + const auto &SRE = checkNode<ObjCSubscriptRefExpr>( + BinOp.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/2); + const auto &Cast = checkNode<ImplicitCastExpr>( + SRE.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + checkNode<DeclRefExpr>(Cast.Children[0], + SourceSelectionKind::InsideSelection); + const auto &POE2 = checkNode<PseudoObjectExpr>( + SRE.Children[1], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + const auto &PRE = checkNode<ObjCPropertyRefExpr>( + POE2.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + const auto &Cast2 = checkNode<ImplicitCastExpr>( + PRE.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + checkNode<DeclRefExpr>(Cast2.Children[0], + SourceSelectionKind::InsideSelection); + checkNode<DeclRefExpr>(BinOp.Children[1], + SourceSelectionKind::InsideSelection); + }, + SelectionFinderVisitor::Lang_OBJC); +} + } // end anonymous namespace |