From c0e1d923231d42fb0ac86e56a29ffc5c754657ca Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 11 Nov 2010 08:05:18 +0000 Subject: [PATCH] Generalize data-recursive visitation in CursorVisitor to also handle MemberExprs and CXXCallMemberExprs. This scheme is hopefully general enough to extend to the rest of the visitor if necessary. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118782 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Index/recursive-member-access.c | 532 +++++++++++++++++++++++++++ tools/libclang/CIndex.cpp | 294 +++++++++------ 2 files changed, 707 insertions(+), 119 deletions(-) create mode 100644 test/Index/recursive-member-access.c diff --git a/test/Index/recursive-member-access.c b/test/Index/recursive-member-access.c new file mode 100644 index 0000000000..c76fa0e504 --- /dev/null +++ b/test/Index/recursive-member-access.c @@ -0,0 +1,532 @@ +struct rdar8650865 { + struct rdar8650865 *first; + int x; +}; + +int test_rdar8650865(struct rdar8650865 *s) { + return ((((((s->first)->first) + ->first) + ->first) + ->first) + ->first) + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->first + ->x; +} + +// RUN: c-index-test -test-load-source all %s | FileCheck %s +// CHECK: 1:8: StructDecl=rdar8650865:1:8 (Definition) Extent=[1:1 - 4:2] +// CHECK: 2:23: FieldDecl=first:2:23 (Definition) Extent=[2:23 - 2:28] +// CHECK: 2:10: TypeRef=struct rdar8650865:1:8 Extent=[2:10 - 2:21] +// CHECK: 3:7: FieldDecl=x:3:7 (Definition) Extent=[3:7 - 3:8] +// CHECK: 6:5: FunctionDecl=test_rdar8650865:6:5 (Definition) Extent=[6:5 - 124:2] +// CHECK: 6:42: ParmDecl=s:6:42 (Definition) Extent=[6:29 - 6:43] +// CHECK: 6:29: TypeRef=struct rdar8650865:1:8 Extent=[6:29 - 6:40] +// CHECK: 6:45: UnexposedStmt= Extent=[6:45 - 124:2] +// CHECK: 7:3: UnexposedStmt= Extent=[7:3 - 123:8] +// CHECK: 123:7: MemberRefExpr=x:3:7 Extent=[7:10 - 123:8] +// CHECK: 122:7: MemberRefExpr=first:2:23 Extent=[7:10 - 122:12] +// CHECK: 121:7: MemberRefExpr=first:2:23 Extent=[7:10 - 121:12] +// CHECK: 120:7: MemberRefExpr=first:2:23 Extent=[7:10 - 120:12] +// CHECK: 119:7: MemberRefExpr=first:2:23 Extent=[7:10 - 119:12] +// CHECK: 118:7: MemberRefExpr=first:2:23 Extent=[7:10 - 118:12] +// CHECK: 117:7: MemberRefExpr=first:2:23 Extent=[7:10 - 117:12] +// CHECK: 116:7: MemberRefExpr=first:2:23 Extent=[7:10 - 116:12] +// CHECK: 115:7: MemberRefExpr=first:2:23 Extent=[7:10 - 115:12] +// CHECK: 114:7: MemberRefExpr=first:2:23 Extent=[7:10 - 114:12] +// CHECK: 113:7: MemberRefExpr=first:2:23 Extent=[7:10 - 113:12] +// CHECK: 112:7: MemberRefExpr=first:2:23 Extent=[7:10 - 112:12] +// CHECK: 111:7: MemberRefExpr=first:2:23 Extent=[7:10 - 111:12] +// CHECK: 110:7: MemberRefExpr=first:2:23 Extent=[7:10 - 110:12] +// CHECK: 109:7: MemberRefExpr=first:2:23 Extent=[7:10 - 109:12] +// CHECK: 108:7: MemberRefExpr=first:2:23 Extent=[7:10 - 108:12] +// CHECK: 107:7: MemberRefExpr=first:2:23 Extent=[7:10 - 107:12] +// CHECK: 106:7: MemberRefExpr=first:2:23 Extent=[7:10 - 106:12] +// CHECK: 105:7: MemberRefExpr=first:2:23 Extent=[7:10 - 105:12] +// CHECK: 104:7: MemberRefExpr=first:2:23 Extent=[7:10 - 104:12] +// CHECK: 103:7: MemberRefExpr=first:2:23 Extent=[7:10 - 103:12] +// CHECK: 102:7: MemberRefExpr=first:2:23 Extent=[7:10 - 102:12] +// CHECK: 101:7: MemberRefExpr=first:2:23 Extent=[7:10 - 101:12] +// CHECK: 100:7: MemberRefExpr=first:2:23 Extent=[7:10 - 100:12] +// CHECK: 99:7: MemberRefExpr=first:2:23 Extent=[7:10 - 99:12] +// CHECK: 98:7: MemberRefExpr=first:2:23 Extent=[7:10 - 98:12] +// CHECK: 97:7: MemberRefExpr=first:2:23 Extent=[7:10 - 97:12] +// CHECK: 96:7: MemberRefExpr=first:2:23 Extent=[7:10 - 96:12] +// CHECK: 95:7: MemberRefExpr=first:2:23 Extent=[7:10 - 95:12] +// CHECK: 94:7: MemberRefExpr=first:2:23 Extent=[7:10 - 94:12] +// CHECK: 93:7: MemberRefExpr=first:2:23 Extent=[7:10 - 93:12] +// CHECK: 92:7: MemberRefExpr=first:2:23 Extent=[7:10 - 92:12] +// CHECK: 91:7: MemberRefExpr=first:2:23 Extent=[7:10 - 91:12] +// CHECK: 90:7: MemberRefExpr=first:2:23 Extent=[7:10 - 90:12] +// CHECK: 89:7: MemberRefExpr=first:2:23 Extent=[7:10 - 89:12] +// CHECK: 88:7: MemberRefExpr=first:2:23 Extent=[7:10 - 88:12] +// CHECK: 87:7: MemberRefExpr=first:2:23 Extent=[7:10 - 87:12] +// CHECK: 86:7: MemberRefExpr=first:2:23 Extent=[7:10 - 86:12] +// CHECK: 85:7: MemberRefExpr=first:2:23 Extent=[7:10 - 85:12] +// CHECK: 84:7: MemberRefExpr=first:2:23 Extent=[7:10 - 84:12] +// CHECK: 83:7: MemberRefExpr=first:2:23 Extent=[7:10 - 83:12] +// CHECK: 82:7: MemberRefExpr=first:2:23 Extent=[7:10 - 82:12] +// CHECK: 81:7: MemberRefExpr=first:2:23 Extent=[7:10 - 81:12] +// CHECK: 80:7: MemberRefExpr=first:2:23 Extent=[7:10 - 80:12] +// CHECK: 79:7: MemberRefExpr=first:2:23 Extent=[7:10 - 79:12] +// CHECK: 78:7: MemberRefExpr=first:2:23 Extent=[7:10 - 78:12] +// CHECK: 77:7: MemberRefExpr=first:2:23 Extent=[7:10 - 77:12] +// CHECK: 76:7: MemberRefExpr=first:2:23 Extent=[7:10 - 76:12] +// CHECK: 75:7: MemberRefExpr=first:2:23 Extent=[7:10 - 75:12] +// CHECK: 74:7: MemberRefExpr=first:2:23 Extent=[7:10 - 74:12] +// CHECK: 73:7: MemberRefExpr=first:2:23 Extent=[7:10 - 73:12] +// CHECK: 72:7: MemberRefExpr=first:2:23 Extent=[7:10 - 72:12] +// CHECK: 71:7: MemberRefExpr=first:2:23 Extent=[7:10 - 71:12] +// CHECK: 70:7: MemberRefExpr=first:2:23 Extent=[7:10 - 70:12] +// CHECK: 69:7: MemberRefExpr=first:2:23 Extent=[7:10 - 69:12] +// CHECK: 68:7: MemberRefExpr=first:2:23 Extent=[7:10 - 68:12] +// CHECK: 67:7: MemberRefExpr=first:2:23 Extent=[7:10 - 67:12] +// CHECK: 66:7: MemberRefExpr=first:2:23 Extent=[7:10 - 66:12] +// CHECK: 65:7: MemberRefExpr=first:2:23 Extent=[7:10 - 65:12] +// CHECK: 64:7: MemberRefExpr=first:2:23 Extent=[7:10 - 64:12] +// CHECK: 63:7: MemberRefExpr=first:2:23 Extent=[7:10 - 63:12] +// CHECK: 62:7: MemberRefExpr=first:2:23 Extent=[7:10 - 62:12] +// CHECK: 61:7: MemberRefExpr=first:2:23 Extent=[7:10 - 61:12] +// CHECK: 60:7: MemberRefExpr=first:2:23 Extent=[7:10 - 60:12] +// CHECK: 59:7: MemberRefExpr=first:2:23 Extent=[7:10 - 59:12] +// CHECK: 58:7: MemberRefExpr=first:2:23 Extent=[7:10 - 58:12] +// CHECK: 57:7: MemberRefExpr=first:2:23 Extent=[7:10 - 57:12] +// CHECK: 56:7: MemberRefExpr=first:2:23 Extent=[7:10 - 56:12] +// CHECK: 55:7: MemberRefExpr=first:2:23 Extent=[7:10 - 55:12] +// CHECK: 54:7: MemberRefExpr=first:2:23 Extent=[7:10 - 54:12] +// CHECK: 53:7: MemberRefExpr=first:2:23 Extent=[7:10 - 53:12] +// CHECK: 52:7: MemberRefExpr=first:2:23 Extent=[7:10 - 52:12] +// CHECK: 51:7: MemberRefExpr=first:2:23 Extent=[7:10 - 51:12] +// CHECK: 50:7: MemberRefExpr=first:2:23 Extent=[7:10 - 50:12] +// CHECK: 49:7: MemberRefExpr=first:2:23 Extent=[7:10 - 49:12] +// CHECK: 48:7: MemberRefExpr=first:2:23 Extent=[7:10 - 48:12] +// CHECK: 47:7: MemberRefExpr=first:2:23 Extent=[7:10 - 47:12] +// CHECK: 46:7: MemberRefExpr=first:2:23 Extent=[7:10 - 46:12] +// CHECK: 45:7: MemberRefExpr=first:2:23 Extent=[7:10 - 45:12] +// CHECK: 44:7: MemberRefExpr=first:2:23 Extent=[7:10 - 44:12] +// CHECK: 43:7: MemberRefExpr=first:2:23 Extent=[7:10 - 43:12] +// CHECK: 42:7: MemberRefExpr=first:2:23 Extent=[7:10 - 42:12] +// CHECK: 41:7: MemberRefExpr=first:2:23 Extent=[7:10 - 41:12] +// CHECK: 40:7: MemberRefExpr=first:2:23 Extent=[7:10 - 40:12] +// CHECK: 39:7: MemberRefExpr=first:2:23 Extent=[7:10 - 39:12] +// CHECK: 38:7: MemberRefExpr=first:2:23 Extent=[7:10 - 38:12] +// CHECK: 37:7: MemberRefExpr=first:2:23 Extent=[7:10 - 37:12] +// CHECK: 36:7: MemberRefExpr=first:2:23 Extent=[7:10 - 36:12] +// CHECK: 35:7: MemberRefExpr=first:2:23 Extent=[7:10 - 35:12] +// CHECK: 34:7: MemberRefExpr=first:2:23 Extent=[7:10 - 34:12] +// CHECK: 33:7: MemberRefExpr=first:2:23 Extent=[7:10 - 33:12] +// CHECK: 32:7: MemberRefExpr=first:2:23 Extent=[7:10 - 32:12] +// CHECK: 31:7: MemberRefExpr=first:2:23 Extent=[7:10 - 31:12] +// CHECK: 30:7: MemberRefExpr=first:2:23 Extent=[7:10 - 30:12] +// CHECK: 29:7: MemberRefExpr=first:2:23 Extent=[7:10 - 29:12] +// CHECK: 28:7: MemberRefExpr=first:2:23 Extent=[7:10 - 28:12] +// CHECK: 27:7: MemberRefExpr=first:2:23 Extent=[7:10 - 27:12] +// CHECK: 26:7: MemberRefExpr=first:2:23 Extent=[7:10 - 26:12] +// CHECK: 25:7: MemberRefExpr=first:2:23 Extent=[7:10 - 25:12] +// CHECK: 24:7: MemberRefExpr=first:2:23 Extent=[7:10 - 24:12] +// CHECK: 23:7: MemberRefExpr=first:2:23 Extent=[7:10 - 23:12] +// CHECK: 22:7: MemberRefExpr=first:2:23 Extent=[7:10 - 22:12] +// CHECK: 21:7: MemberRefExpr=first:2:23 Extent=[7:10 - 21:12] +// CHECK: 20:7: MemberRefExpr=first:2:23 Extent=[7:10 - 20:12] +// CHECK: 19:7: MemberRefExpr=first:2:23 Extent=[7:10 - 19:12] +// CHECK: 18:7: MemberRefExpr=first:2:23 Extent=[7:10 - 18:12] +// CHECK: 17:7: MemberRefExpr=first:2:23 Extent=[7:10 - 17:12] +// CHECK: 16:7: MemberRefExpr=first:2:23 Extent=[7:10 - 16:12] +// CHECK: 15:7: MemberRefExpr=first:2:23 Extent=[7:10 - 15:12] +// CHECK: 14:7: MemberRefExpr=first:2:23 Extent=[7:10 - 14:12] +// CHECK: 13:7: MemberRefExpr=first:2:23 Extent=[7:10 - 13:12] +// CHECK: 12:7: MemberRefExpr=first:2:23 Extent=[7:10 - 12:12] +// CHECK: 11:7: MemberRefExpr=first:2:23 Extent=[7:11 - 11:12] +// CHECK: 10:7: MemberRefExpr=first:2:23 Extent=[7:12 - 10:12] +// CHECK: 9:7: MemberRefExpr=first:2:23 Extent=[7:13 - 9:12] +// CHECK: 8:7: MemberRefExpr=first:2:23 Extent=[7:14 - 8:12] +// CHECK: 7:27: MemberRefExpr=first:2:23 Extent=[7:15 - 7:32] +// CHECK: 7:19: MemberRefExpr=first:2:23 Extent=[7:16 - 7:24] +// CHECK: 7:16: DeclRefExpr=s:6:42 Extent=[7:16 - 7:17] + +// RUN: c-index-test -test-annotate-tokens=%s:1:1:124:1 %s | FileCheck -check-prefix=CHECK-tokens %s +// CHECK-tokens: Keyword: "struct" [1:1 - 1:7] StructDecl=rdar8650865:1:8 (Definition) +// CHECK-tokens: Identifier: "rdar8650865" [1:8 - 1:19] StructDecl=rdar8650865:1:8 (Definition) +// CHECK-tokens: Punctuation: "{" [1:20 - 1:21] StructDecl=rdar8650865:1:8 (Definition) +// CHECK-tokens: Keyword: "struct" [2:3 - 2:9] StructDecl=rdar8650865:1:8 (Definition) +// CHECK-tokens: Identifier: "rdar8650865" [2:10 - 2:21] TypeRef=struct rdar8650865:1:8 +// CHECK-tokens: Punctuation: "*" [2:22 - 2:23] FieldDecl=first:2:23 (Definition) +// CHECK-tokens: Identifier: "first" [2:23 - 2:28] FieldDecl=first:2:23 (Definition) +// CHECK-tokens: Punctuation: ";" [2:28 - 2:29] StructDecl=rdar8650865:1:8 (Definition) +// CHECK-tokens: Keyword: "int" [3:3 - 3:6] FieldDecl=x:3:7 (Definition) +// CHECK-tokens: Identifier: "x" [3:7 - 3:8] FieldDecl=x:3:7 (Definition) +// CHECK-tokens: Punctuation: ";" [3:8 - 3:9] StructDecl=rdar8650865:1:8 (Definition) +// CHECK-tokens: Punctuation: "}" [4:1 - 4:2] StructDecl=rdar8650865:1:8 (Definition) +// CHECK-tokens: Punctuation: ";" [4:2 - 4:3] +// CHECK-tokens: Keyword: "int" [6:1 - 6:4] FunctionDecl=test_rdar8650865:6:5 (Definition) +// CHECK-tokens: Identifier: "test_rdar8650865" [6:5 - 6:21] FunctionDecl=test_rdar8650865:6:5 (Definition) +// CHECK-tokens: Punctuation: "(" [6:21 - 6:22] FunctionDecl=test_rdar8650865:6:5 (Definition) +// CHECK-tokens: Keyword: "struct" [6:22 - 6:28] FunctionDecl=test_rdar8650865:6:5 (Definition) +// CHECK-tokens: Identifier: "rdar8650865" [6:29 - 6:40] TypeRef=struct rdar8650865:1:8 +// CHECK-tokens: Punctuation: "*" [6:41 - 6:42] ParmDecl=s:6:42 (Definition) +// CHECK-tokens: Identifier: "s" [6:42 - 6:43] ParmDecl=s:6:42 (Definition) +// CHECK-tokens: Punctuation: ")" [6:43 - 6:44] FunctionDecl=test_rdar8650865:6:5 (Definition) +// CHECK-tokens: Punctuation: "{" [6:45 - 6:46] UnexposedStmt= +// CHECK-tokens: Keyword: "return" [7:3 - 7:9] UnexposedStmt= +// CHECK-tokens: Punctuation: "(" [7:10 - 7:11] UnexposedExpr= +// CHECK-tokens: Punctuation: "(" [7:11 - 7:12] UnexposedExpr= +// CHECK-tokens: Punctuation: "(" [7:12 - 7:13] UnexposedExpr= +// CHECK-tokens: Punctuation: "(" [7:13 - 7:14] UnexposedExpr= +// CHECK-tokens: Punctuation: "(" [7:14 - 7:15] UnexposedExpr= +// CHECK-tokens: Punctuation: "(" [7:15 - 7:16] UnexposedExpr= +// CHECK-tokens: Identifier: "s" [7:16 - 7:17] DeclRefExpr=s:6:42 +// CHECK-tokens: Punctuation: "->" [7:17 - 7:19] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [7:19 - 7:24] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: ")" [7:24 - 7:25] UnexposedExpr= +// CHECK-tokens: Punctuation: "->" [7:25 - 7:27] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [7:27 - 7:32] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: ")" [7:32 - 7:33] UnexposedExpr= +// CHECK-tokens: Punctuation: "->" [8:5 - 8:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [8:7 - 8:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: ")" [8:12 - 8:13] UnexposedExpr= +// CHECK-tokens: Punctuation: "->" [9:5 - 9:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [9:7 - 9:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: ")" [9:12 - 9:13] UnexposedExpr= +// CHECK-tokens: Punctuation: "->" [10:5 - 10:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [10:7 - 10:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: ")" [10:12 - 10:13] UnexposedExpr= +// CHECK-tokens: Punctuation: "->" [11:5 - 11:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [11:7 - 11:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: ")" [11:12 - 11:13] UnexposedExpr= +// CHECK-tokens: Punctuation: "->" [12:5 - 12:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [12:7 - 12:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [13:5 - 13:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [13:7 - 13:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [14:5 - 14:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [14:7 - 14:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [15:5 - 15:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [15:7 - 15:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [16:5 - 16:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [16:7 - 16:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [17:5 - 17:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [17:7 - 17:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [18:5 - 18:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [18:7 - 18:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [19:5 - 19:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [19:7 - 19:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [20:5 - 20:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [20:7 - 20:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [21:5 - 21:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [21:7 - 21:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [22:5 - 22:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [22:7 - 22:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [23:5 - 23:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [23:7 - 23:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [24:5 - 24:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [24:7 - 24:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [25:5 - 25:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [25:7 - 25:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [26:5 - 26:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [26:7 - 26:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [27:5 - 27:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [27:7 - 27:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [28:5 - 28:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [28:7 - 28:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [29:5 - 29:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [29:7 - 29:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [30:5 - 30:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [30:7 - 30:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [31:5 - 31:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [31:7 - 31:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [32:5 - 32:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [32:7 - 32:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [33:5 - 33:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [33:7 - 33:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [34:5 - 34:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [34:7 - 34:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [35:5 - 35:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [35:7 - 35:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [36:5 - 36:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [36:7 - 36:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [37:5 - 37:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [37:7 - 37:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [38:5 - 38:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [38:7 - 38:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [39:5 - 39:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [39:7 - 39:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [40:5 - 40:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [40:7 - 40:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [41:5 - 41:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [41:7 - 41:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [42:5 - 42:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [42:7 - 42:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [43:5 - 43:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [43:7 - 43:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [44:5 - 44:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [44:7 - 44:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [45:5 - 45:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [45:7 - 45:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [46:5 - 46:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [46:7 - 46:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [47:5 - 47:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [47:7 - 47:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [48:5 - 48:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [48:7 - 48:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [49:5 - 49:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [49:7 - 49:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [50:5 - 50:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [50:7 - 50:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [51:5 - 51:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [51:7 - 51:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [52:5 - 52:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [52:7 - 52:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [53:5 - 53:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [53:7 - 53:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [54:5 - 54:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [54:7 - 54:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [55:5 - 55:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [55:7 - 55:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [56:5 - 56:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [56:7 - 56:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [57:5 - 57:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [57:7 - 57:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [58:5 - 58:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [58:7 - 58:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [59:5 - 59:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [59:7 - 59:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [60:5 - 60:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [60:7 - 60:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [61:5 - 61:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [61:7 - 61:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [62:5 - 62:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [62:7 - 62:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [63:5 - 63:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [63:7 - 63:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [64:5 - 64:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [64:7 - 64:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [65:5 - 65:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [65:7 - 65:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [66:5 - 66:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [66:7 - 66:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [67:5 - 67:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [67:7 - 67:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [68:5 - 68:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [68:7 - 68:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [69:5 - 69:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [69:7 - 69:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [70:5 - 70:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [70:7 - 70:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [71:5 - 71:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [71:7 - 71:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [72:5 - 72:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [72:7 - 72:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [73:5 - 73:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [73:7 - 73:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [74:5 - 74:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [74:7 - 74:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [75:5 - 75:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [75:7 - 75:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [76:5 - 76:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [76:7 - 76:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [77:5 - 77:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [77:7 - 77:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [78:5 - 78:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [78:7 - 78:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [79:5 - 79:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [79:7 - 79:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [80:5 - 80:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [80:7 - 80:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [81:5 - 81:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [81:7 - 81:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [82:5 - 82:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [82:7 - 82:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [83:5 - 83:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [83:7 - 83:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [84:5 - 84:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [84:7 - 84:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [85:5 - 85:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [85:7 - 85:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [86:5 - 86:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [86:7 - 86:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [87:5 - 87:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [87:7 - 87:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [88:5 - 88:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [88:7 - 88:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [89:5 - 89:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [89:7 - 89:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [90:5 - 90:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [90:7 - 90:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [91:5 - 91:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [91:7 - 91:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [92:5 - 92:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [92:7 - 92:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [93:5 - 93:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [93:7 - 93:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [94:5 - 94:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [94:7 - 94:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [95:5 - 95:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [95:7 - 95:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [96:5 - 96:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [96:7 - 96:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [97:5 - 97:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [97:7 - 97:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [98:5 - 98:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [98:7 - 98:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [99:5 - 99:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [99:7 - 99:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [100:5 - 100:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [100:7 - 100:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [101:5 - 101:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [101:7 - 101:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [102:5 - 102:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [102:7 - 102:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [103:5 - 103:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [103:7 - 103:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [104:5 - 104:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [104:7 - 104:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [105:5 - 105:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [105:7 - 105:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [106:5 - 106:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [106:7 - 106:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [107:5 - 107:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [107:7 - 107:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [108:5 - 108:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [108:7 - 108:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [109:5 - 109:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [109:7 - 109:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [110:5 - 110:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [110:7 - 110:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [111:5 - 111:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [111:7 - 111:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [112:5 - 112:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [112:7 - 112:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [113:5 - 113:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [113:7 - 113:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [114:5 - 114:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [114:7 - 114:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [115:5 - 115:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [115:7 - 115:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [116:5 - 116:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [116:7 - 116:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [117:5 - 117:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [117:7 - 117:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [118:5 - 118:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [118:7 - 118:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [119:5 - 119:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [119:7 - 119:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [120:5 - 120:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [120:7 - 120:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [121:5 - 121:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [121:7 - 121:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [122:5 - 122:7] MemberRefExpr=first:2:23 +// CHECK-tokens: Identifier: "first" [122:7 - 122:12] MemberRefExpr=first:2:23 +// CHECK-tokens: Punctuation: "->" [123:5 - 123:7] MemberRefExpr=x:3:7 +// CHECK-tokens: Identifier: "x" [123:7 - 123:8] MemberRefExpr=x:3:7 +// CHECK-tokens: Punctuation: ";" [123:8 - 123:9] UnexposedStmt= +// CHECK-tokens: Punctuation: "}" [124:1 - 124:2] UnexposedStmt= + + diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 8de774cb88..de28875de8 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -123,6 +123,36 @@ CXSourceRange cxloc::translateSourceRange(const SourceManager &SM, //===----------------------------------------------------------------------===// namespace { + +class VisitorJob { +public: + enum Kind { StmtVisitKind, MemberExprPartsKind }; +protected: + void *data; + CXCursor parent; + Kind K; + VisitorJob(void *d, CXCursor C, Kind k) : data(d), parent(C), K(k) {} +public: + Kind getKind() const { return K; } + const CXCursor &getParent() const { return parent; } + static bool classof(VisitorJob *VJ) { return true; } +}; + +typedef llvm::SmallVector VisitorWorkList; + +#define DEF_JOB(NAME, DATA, KIND)\ +class NAME : public VisitorJob {\ +public:\ + NAME(DATA *d, CXCursor parent) : VisitorJob(d, parent, VisitorJob::KIND) {}\ + static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\ + DATA *get() const { return static_cast(data); }\ +}; + +DEF_JOB(StmtVisit, Stmt, StmtVisitKind) +DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind) + +#undef DEF_JOB + // Cursor visitor. class CursorVisitor : public DeclVisitor, @@ -300,14 +330,12 @@ public: bool VisitDeclRefExpr(DeclRefExpr *E); bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E); bool VisitBlockExpr(BlockExpr *B); - bool VisitBinaryOperator(BinaryOperator *B); bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E); bool VisitExplicitCastExpr(ExplicitCastExpr *E); bool VisitObjCMessageExpr(ObjCMessageExpr *E); bool VisitObjCEncodeExpr(ObjCEncodeExpr *E); bool VisitOffsetOfExpr(OffsetOfExpr *E); bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); - bool VisitMemberExpr(MemberExpr *E); bool VisitAddrLabelExpr(AddrLabelExpr *E); bool VisitTypesCompatibleExpr(TypesCompatibleExpr *E); bool VisitVAArgExpr(VAArgExpr *E); @@ -326,6 +354,18 @@ public: bool VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E); bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); bool VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E); + +#define DATA_RECURSIVE_VISIT(NAME)\ +bool Visit##NAME(NAME *S) { return VisitDataRecursive(S); } + DATA_RECURSIVE_VISIT(BinaryOperator) + DATA_RECURSIVE_VISIT(MemberExpr) + DATA_RECURSIVE_VISIT(CXXMemberCallExpr) + + // Data-recursive visitor functions. + bool IsInRegionOfInterest(CXCursor C); + bool RunVisitorWorkList(VisitorWorkList &WL); + void EnqueueWorkList(VisitorWorkList &WL, Stmt *S); + bool VisitDataRecursive(Stmt *S); }; } // end anonymous namespace @@ -1531,95 +1571,6 @@ bool CursorVisitor::VisitForStmt(ForStmt *S) { return false; } -bool CursorVisitor::VisitBinaryOperator(BinaryOperator *B) { - // We can blow the stack in some cases where we have deeply nested BinaryOperators, - // often involving logical expressions, e.g.: '(x || y) || (y || z) || ... - // To handle this, we visitation of BinaryOperators is data recursive instead of - // directly recursive. This makes the algorithm more complicated, but handles - // arbitrary depths. We should consider making the entire CursorVisitor data - // recursive. - typedef std::pair - WorkListItem; - typedef llvm::SmallVector WorkList; - - CXCursor Cursor = MakeCXCursor(B, StmtParent, TU); - WorkList WL; - WL.push_back(std::make_pair(B->getRHS(), Cursor)); - WL.push_back(std::make_pair(B->getLHS(), Cursor)); - - while (!WL.empty()) { - // Dequeue the worklist item. - WorkListItem LI = WL.back(); WL.pop_back(); Expr *Ex = LI.first; - - // Set the Parent field, then back to its old value once we're done. - SetParentRAII SetParent(Parent, StmtParent, LI.second); - - // Update the current cursor. - Cursor = MakeCXCursor(Ex, StmtParent, TU); - - // For non-BinaryOperators, perform the default visitation. - if (!isa(Ex)) { - if (Visit(Cursor)) { - // Skip all other items in the worklist that also have - // the same parent. - while (!WL.empty()) { - const WorkListItem &LIb = WL.back(); - if (LIb.second == LI.second) - WL.pop_back(); - else - break; - } - // If the worklist is now empty, we should immediately return - // to the caller, since this is the base case. - if (WL.empty()) - return true; - } - continue; - } - // For BinaryOperators, perform a custom visitation where we add the - // children to a worklist. - if (RegionOfInterest.isValid()) { - SourceRange Range = getRawCursorExtent(Cursor); - if (Range.isInvalid() || CompareRegionOfInterest(Range)) { - // Proceed to the next item on the worklist. - continue; - } - } - switch (Visitor(Cursor, Parent, ClientData)) { - case CXChildVisit_Break: { - // Skip all other items in the worklist that also have - // the same parent. - while (!WL.empty()) { - const WorkListItem &LIb = WL.back(); - if (LIb.second == LI.second) - WL.pop_back(); - else - break; - } - // If the worklist is now empty, we should immediately return - // to the caller, since this is the base case. - if (WL.empty()) - return true; - break; - } - case CXChildVisit_Continue: - break; - case CXChildVisit_Recurse: { - BinaryOperator *B = cast(Ex); - // FIXME: Note that we ignore parentheses, since these are often - // unimportant during cursor visitation. If we care about these, we - // can unroll the visitation one more level. Alternatively, we - // can convert the entire visitor to be data recursive, eliminating - // all edge cases. - WL.push_back(std::make_pair(B->getRHS()->IgnoreParens(), Cursor)); - WL.push_back(std::make_pair(B->getLHS()->IgnoreParens(), Cursor)); - break; - } - } - } - return false; -} - bool CursorVisitor::VisitDeclRefExpr(DeclRefExpr *E) { // Visit nested-name-specifier, if present. if (NestedNameSpecifier *Qualifier = E->getQualifier()) @@ -1716,34 +1667,6 @@ bool CursorVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { return VisitExpr(E); } -bool CursorVisitor::VisitMemberExpr(MemberExpr *E) { - // Visit the base expression. - if (Visit(MakeCXCursor(E->getBase(), StmtParent, TU))) - return true; - - // Visit the nested-name-specifier - if (NestedNameSpecifier *Qualifier = E->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) - return true; - - // Visit the declaration name. - if (VisitDeclarationNameInfo(E->getMemberNameInfo())) - return true; - - // Visit the explicitly-specified template arguments, if any. - if (E->hasExplicitTemplateArgs()) { - for (const TemplateArgumentLoc *Arg = E->getTemplateArgs(), - *ArgEnd = Arg + E->getNumTemplateArgs(); - Arg != ArgEnd; - ++Arg) { - if (VisitTemplateArgumentLoc(*Arg)) - return true; - } - } - - return false; -} - bool CursorVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) { if (TypeSourceInfo *TSInfo = E->getTypeInfoAsWritten()) if (Visit(TSInfo->getTypeLoc())) @@ -2026,6 +1949,139 @@ bool CursorVisitor::VisitAttributes(Decl *D) { return false; } +//===----------------------------------------------------------------------===// +// Data-recursive visitor methods. +//===----------------------------------------------------------------------===// + +void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) { + CXCursor C = MakeCXCursor(S, StmtParent, TU); + switch (S->getStmtClass()) { + default: { + unsigned size = WL.size(); + for (Stmt::child_iterator Child = S->child_begin(), + ChildEnd = S->child_end(); Child != ChildEnd; ++Child) { + if (Stmt *child = *Child) { + WL.push_back(StmtVisit(child, C)); + } + } + + if (size == WL.size()) + return; + + // Now reverse the entries we just added. This will match the DFS + // ordering performed by the worklist. + VisitorWorkList::iterator I = WL.begin() + size, E = WL.end(); + std::reverse(I, E); + break; + } + case Stmt::ParenExprClass: { + WL.push_back(StmtVisit(cast(S)->getSubExpr(), C)); + break; + } + case Stmt::BinaryOperatorClass: { + BinaryOperator *B = cast(S); + WL.push_back(StmtVisit(B->getRHS(), C)); + WL.push_back(StmtVisit(B->getLHS(), C)); + break; + } + case Stmt::MemberExprClass: { + MemberExpr *M = cast(S); + WL.push_back(MemberExprParts(M, C)); + WL.push_back(StmtVisit(M->getBase(), C)); + break; + } + } +} + +bool CursorVisitor::IsInRegionOfInterest(CXCursor C) { + if (RegionOfInterest.isValid()) { + SourceRange Range = getRawCursorExtent(C); + if (Range.isInvalid() || CompareRegionOfInterest(Range)) + return false; + } + return true; +} + +bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { + while (!WL.empty()) { + // Dequeue the worklist item. + VisitorJob LI = WL.back(); WL.pop_back(); + + // Set the Parent field, then back to its old value once we're done. + SetParentRAII SetParent(Parent, StmtParent, LI.getParent()); + + switch (LI.getKind()) { + case VisitorJob::StmtVisitKind: { + // Update the current cursor. + Stmt *S = cast(LI).get(); + CXCursor Cursor = MakeCXCursor(S, StmtParent, TU); + + switch (S->getStmtClass()) { + default: { + // Perform default visitation for other cases. + if (Visit(Cursor)) + return true; + continue; + } + case Stmt::CallExprClass: + case Stmt::CXXMemberCallExprClass: + case Stmt::ParenExprClass: + case Stmt::MemberExprClass: + case Stmt::BinaryOperatorClass: { + if (!IsInRegionOfInterest(Cursor)) + continue; + switch (Visitor(Cursor, Parent, ClientData)) { + case CXChildVisit_Break: + return true; + case CXChildVisit_Continue: + break; + case CXChildVisit_Recurse: + EnqueueWorkList(WL, S); + break; + } + } + } + continue; + } + case VisitorJob::MemberExprPartsKind: { + // Handle the other pieces in the MemberExpr besides the base. + MemberExpr *M = cast(LI).get(); + + // Visit the nested-name-specifier + if (NestedNameSpecifier *Qualifier = M->getQualifier()) + if (VisitNestedNameSpecifier(Qualifier, M->getQualifierRange())) + return true; + + // Visit the declaration name. + if (VisitDeclarationNameInfo(M->getMemberNameInfo())) + return true; + + // Visit the explicitly-specified template arguments, if any. + if (M->hasExplicitTemplateArgs()) { + for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(), + *ArgEnd = Arg + M->getNumTemplateArgs(); + Arg != ArgEnd; ++Arg) { + if (VisitTemplateArgumentLoc(*Arg)) + return true; + } + } + continue; + } + } + } + return false; +} + +bool CursorVisitor::VisitDataRecursive(Stmt *S) { + VisitorWorkList WL; + EnqueueWorkList(WL, S); + return RunVisitorWorkList(WL); +} + +//===----------------------------------------------------------------------===// +// Misc. API hooks. +//===----------------------------------------------------------------------===// + static llvm::sys::Mutex EnableMultithreadingMutex; static bool EnabledMultithreading;