diff options
Diffstat (limited to 'test/Tooling')
-rw-r--r-- | test/Tooling/Inputs/clang-diff-basic-src.cpp | 33 | ||||
-rw-r--r-- | test/Tooling/Inputs/fixed-header.h | 1 | ||||
-rw-r--r-- | test/Tooling/clang-diff-args.test | 12 | ||||
-rw-r--r-- | test/Tooling/clang-diff-ast.cpp | 92 | ||||
-rw-r--r-- | test/Tooling/clang-diff-basic.cpp | 57 | ||||
-rw-r--r-- | test/Tooling/clang-diff-bottomup.cpp | 39 | ||||
-rw-r--r-- | test/Tooling/clang-diff-html.test | 36 | ||||
-rw-r--r-- | test/Tooling/clang-diff-json.cpp | 27 | ||||
-rw-r--r-- | test/Tooling/clang-diff-opt.cpp | 45 | ||||
-rw-r--r-- | test/Tooling/clang-diff-topdown.cpp | 83 | ||||
-rw-r--r-- | test/Tooling/fixed-database.cpp | 19 |
11 files changed, 444 insertions, 0 deletions
diff --git a/test/Tooling/Inputs/clang-diff-basic-src.cpp b/test/Tooling/Inputs/clang-diff-basic-src.cpp new file mode 100644 index 0000000000000..8f15232916d3d --- /dev/null +++ b/test/Tooling/Inputs/clang-diff-basic-src.cpp @@ -0,0 +1,33 @@ +namespace src { + +void foo() { + int x = 321; +} + +void main() { foo(); }; + +const char *a = "foo"; + +typedef unsigned int nat; + +int p = 1 * 2 * 3 * 4; +int squared = p * p; + +class X { + const char *foo(int i) { + if (i == 0) + return "foo"; + return 0; + } + +public: + X(){}; + + int id(int i) { return i; } +}; +} + +void m() { int x = 0 + 0 + 0; } +int um = 1 * 2 + 3; + +void f1() {{ (void) __func__;;; }} diff --git a/test/Tooling/Inputs/fixed-header.h b/test/Tooling/Inputs/fixed-header.h new file mode 100644 index 0000000000000..4ce318f3a4e1b --- /dev/null +++ b/test/Tooling/Inputs/fixed-header.h @@ -0,0 +1 @@ +#define SECRET_SYMBOL 1 diff --git a/test/Tooling/clang-diff-args.test b/test/Tooling/clang-diff-args.test new file mode 100644 index 0000000000000..a4ce1ea92508f --- /dev/null +++ b/test/Tooling/clang-diff-args.test @@ -0,0 +1,12 @@ +RUN: echo a > %t.cpp + +CHECK: unknown type name 'X' + +check adding compiler cflags +RUN: clang-diff -ast-dump -extra-arg=-Da=X %t.cpp -- 2>&1 | FileCheck %s +RUN: clang-diff -ast-dump -extra-arg-before=-Da=X %t.cpp -- 2>&1 | FileCheck %s +RUN: clang-diff -ast-dump %t.cpp -- 2>&1 -Da=X | FileCheck %s + +NOMATCH-CHECK-NOT: {{.}} +RUN: clang-diff %S/clang-diff-ast.cpp %S/clang-diff-ast.cpp -- 2>&1 -std=c++11 \ +RUN: | FileCheck -check-prefix=NOMATCH-CHECK -allow-empty %s diff --git a/test/Tooling/clang-diff-ast.cpp b/test/Tooling/clang-diff-ast.cpp new file mode 100644 index 0000000000000..a8efda50a4052 --- /dev/null +++ b/test/Tooling/clang-diff-ast.cpp @@ -0,0 +1,92 @@ +// RUN: clang-diff -ast-dump %s -- -std=c++11 | FileCheck %s + + +// CHECK: {{^}}TranslationUnitDecl(0) +// CHECK: {{^}} NamespaceDecl: test;( +namespace test { + +// CHECK: {{^}} FunctionDecl: :f( +// CHECK: CompoundStmt( +void f() { + // CHECK: VarDecl: i(int)( + // CHECK: IntegerLiteral: 1 + auto i = 1; + // CHECK: FloatingLiteral: 1.5( + auto r = 1.5; + // CHECK: CXXBoolLiteralExpr: true( + auto b = true; + // CHECK: CallExpr( + // CHECK-NOT: ImplicitCastExpr + // CHECK: DeclRefExpr: :f( + f(); + // CHECK: UnaryOperator: ++( + ++i; + // CHECK: BinaryOperator: =( + i = i; +} + +} // end namespace test + +// CHECK: UsingDirectiveDecl: test( +using namespace test; + +// CHECK: TypedefDecl: nat;unsigned int;( +typedef unsigned nat; +// CHECK: TypeAliasDecl: real;double;( +using real = double; + +class Base { +}; + +// CHECK: CXXRecordDecl: X;X;( +class X : Base { + int m; + // CHECK: CXXMethodDecl: :foo(const char *(int) + // CHECK: ParmVarDecl: i(int)( + const char *foo(int i) { + if (i == 0) + // CHECK: StringLiteral: foo( + return "foo"; + // CHECK-NOT: ImplicitCastExpr + return 0; + } + + // CHECK: AccessSpecDecl: public( +public: + int not_initialized; + // CHECK: CXXConstructorDecl: :X(void (char, int){{( __attribute__\(\(thiscall\)\))?}})( + // CHECK-NEXT: ParmVarDecl: s(char) + // CHECK-NEXT: ParmVarDecl: (int) + // CHECK-NEXT: CXXCtorInitializer: Base + // CHECK-NEXT: CXXConstructExpr + // CHECK-NEXT: CXXCtorInitializer: m + // CHECK-NEXT: IntegerLiteral: 0 + X(char s, int) : Base(), m(0) { + // CHECK-NEXT: CompoundStmt + // CHECK: MemberExpr: :m( + int x = m; + } + // CHECK: CXXConstructorDecl: :X(void (char){{( __attribute__\(\(thiscall\)\))?}})( + // CHECK: CXXCtorInitializer: X + X(char s) : X(s, 4) {} +}; + +#define M (void)1 +#define MA(a, b) (void)a, b +// CHECK: FunctionDecl +// CHECK-NEXT: CompoundStmt +void macros() { + M; + MA(1, 2); +} + +#ifndef GUARD +#define GUARD +// CHECK-NEXT: NamespaceDecl +namespace world { +// nodes from other files are excluded, there should be no output here +#include "clang-diff-ast.cpp" +} +// CHECK-NEXT: FunctionDecl: sentinel +void sentinel(); +#endif diff --git a/test/Tooling/clang-diff-basic.cpp b/test/Tooling/clang-diff-basic.cpp new file mode 100644 index 0000000000000..a0c0163530ffa --- /dev/null +++ b/test/Tooling/clang-diff-basic.cpp @@ -0,0 +1,57 @@ +// RUN: clang-diff -dump-matches %S/Inputs/clang-diff-basic-src.cpp %s -- | FileCheck %s + +// CHECK: Match TranslationUnitDecl{{.*}} to TranslationUnitDecl +// CHECK: Match NamespaceDecl: src{{.*}} to NamespaceDecl: dst +namespace dst { +// CHECK-NOT: Match NamespaceDecl: src{{.*}} to NamespaceDecl: inner +namespace inner { +void foo() { + // CHECK: Match IntegerLiteral: 321{{.*}} to IntegerLiteral: 322 + int x = 322; +} +} + +// CHECK: Match DeclRefExpr: :foo{{.*}} to DeclRefExpr: :inner::foo +void main() { inner::foo(); } + +// CHECK: Match StringLiteral: foo{{.*}} to StringLiteral: foo +const char *b = "f" "o" "o"; + +// unsigned is canonicalized to unsigned int +// CHECK: Match TypedefDecl: :nat;unsigned int;{{.*}} to TypedefDecl: :nat;unsigned int; +typedef unsigned nat; + +// CHECK: Match VarDecl: :p(int){{.*}} to VarDecl: :prod(double) +// CHECK: Update VarDecl: :p(int){{.*}} to :prod(double) +// CHECK: Match BinaryOperator: *{{.*}} to BinaryOperator: * +double prod = 1 * 2 * 10; +// CHECK: Update DeclRefExpr +int squared = prod * prod; + +class X { + const char *foo(int i) { + if (i == 0) + return "Bar"; + // CHECK: Insert IfStmt{{.*}} into IfStmt + // CHECK: Insert BinaryOperator: =={{.*}} into IfStmt + else if (i == -1) + return "foo"; + return 0; + } + X(){} +}; +} + +// CHECK: Move CompoundStmt{{.*}} into CompoundStmt +void m() { { int x = 0 + 0 + 0; } } +// CHECK: Update and Move IntegerLiteral: 7{{.*}} into BinaryOperator: +({{.*}}) at 1 +int um = 1 + 7; + +namespace { +// match with parents of different type +// CHECK: Match FunctionDecl: f1{{.*}} to FunctionDecl: (anonymous namespace)::f1 +void f1() {{ (void) __func__;;; }} +} + +// CHECK: Delete AccessSpecDecl: public +// CHECK: Delete CXXMethodDecl diff --git a/test/Tooling/clang-diff-bottomup.cpp b/test/Tooling/clang-diff-bottomup.cpp new file mode 100644 index 0000000000000..bc5d2cbdf4316 --- /dev/null +++ b/test/Tooling/clang-diff-bottomup.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -E %s > %t.src.cpp +// RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST +// RUN: clang-diff -dump-matches -s=0 %t.src.cpp %t.dst.cpp -- | FileCheck %s +// +// Test the bottom-up matching, with maxsize set to 0, so that the optimal matching will never be applied. + +#ifndef DEST + +void f1() { ; {{;}} } +void f2() { ;; {{;}} } + +#else + +// Jaccard similarity threshold is 0.5. + +void f1() { +// CompoundStmt: 3 matched descendants, subtree sizes 4 and 5 +// Jaccard similarity = 3 / (4 + 5 - 3) = 3 / 6 >= 0.5 +// CHECK: Match FunctionDecl: f1(void ())(1) to FunctionDecl: f1(void ())(1) +// CHECK: Match CompoundStmt(2) to CompoundStmt(2) +// CHECK: Match CompoundStmt(4) to CompoundStmt(3) +// CHECK: Match CompoundStmt(5) to CompoundStmt(4) +// CHECK: Match NullStmt(6) to NullStmt(5) + {{;}} ;; +} + +void f2() { +// CompoundStmt: 3 matched descendants, subtree sizes 4 and 5 +// Jaccard similarity = 3 / (5 + 6 - 3) = 3 / 8 < 0.5 +// CHECK-NOT: Match FunctionDecl(9) +// CHECK-NOT: Match CompoundStmt(10) +// CHECK: Match CompoundStmt(11) to CompoundStmt(10) +// CHECK: Match CompoundStmt(12) to CompoundStmt(11) +// CHECK: Match NullStmt(13) to NullStmt(12) +// CHECK-NOT: Match NullStmt(13) + {{;}} ;;; +} + +#endif diff --git a/test/Tooling/clang-diff-html.test b/test/Tooling/clang-diff-html.test new file mode 100644 index 0000000000000..00d9e07d2fcf4 --- /dev/null +++ b/test/Tooling/clang-diff-html.test @@ -0,0 +1,36 @@ +RUN: clang-diff -html %S/Inputs/clang-diff-basic-src.cpp %S/clang-diff-basic.cpp -- | FileCheck %s + +CHECK: <pre><div id='L' class='code'><span id='L0' tid='R0' title='TranslationUnitDecl +CHECK-NEXT: 0 -> 0'> + +match, update +CHECK: <span id='L[[L:[0-9]+]]' tid='R[[R:[0-9]+]]' title='NamespaceDecl +CHECK-NEXT: [[L]] -> [[R]] +CHECK-NEXT: src;' class='u'>namespace src { + +match, move +CHECK: <span id='L[[L:[0-9]+]]' tid='R[[R:[0-9]+]]' title='FunctionDecl +CHECK-NEXT: [[L]] -> [[R]] +CHECK-NEXT: :foo(void ())' class='m'>void foo() + +match +CHECK: <span id='L[[L:[0-9]+]]' tid='R[[R:[0-9]+]]' title='FunctionDecl +CHECK-NEXT: [[L]] -> [[R]] +CHECK-NEXT: :main(void ())'>void main() + +deletion +CHECK: <span id='L[[L:[0-9]+]]' tid='R-1' title='IntegerLiteral +CHECK-NEXT: [[L]] -> -1 +CHECK-NEXT: 4' class='d'>4</span> + +update + move +CHECK: 2' class='u m'>2</span> + +insertion +CHECK: <span id='R[[R:[0-9]+]]' tid='L-1' title='StringLiteral +CHECK-NEXT: -1 -> [[R]] +CHECK-NEXT: Bar' class='i'>"Bar"</span> + +comments +CHECK: // CHECK: Insert IfStmt{{.*}} into IfStmt +CHECK: // CHECK: Delete AccessSpecDecl: public diff --git a/test/Tooling/clang-diff-json.cpp b/test/Tooling/clang-diff-json.cpp new file mode 100644 index 0000000000000..9aac6fa8b15bb --- /dev/null +++ b/test/Tooling/clang-diff-json.cpp @@ -0,0 +1,27 @@ +// RUN: clang-diff -ast-dump-json %s -- \ +// RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ +// RUN: | FileCheck %s + +// CHECK: "begin": 299, +// CHECK: "type": "FieldDecl", +// CHECK: "end": 319, +// CHECK: "type": "CXXRecordDecl", +class A { + int x; +}; + +// CHECK: "children": [ +// CHECK-NEXT: { +// CHECK-NEXT: "begin": +// CHECK-NEXT: "children": [] +// CHECK-NEXT: "end": +// CHECK-NEXT: "id": +// CHECK-NEXT: "type": "CharacterLiteral" +// CHECK-NEXT: } +// CHECK: ] +// CHECK: "type": "VarDecl", +char nl = '\n'; + +// CHECK: "value": "abc \n\t\u0000\u001f" +char s[] = "abc \n\t\0\x1f"; + diff --git a/test/Tooling/clang-diff-opt.cpp b/test/Tooling/clang-diff-opt.cpp new file mode 100644 index 0000000000000..771c6abaecb52 --- /dev/null +++ b/test/Tooling/clang-diff-opt.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -E %s > %t.src.cpp +// RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST +// RUN: clang-diff -dump-matches -s=10 %t.src.cpp %t.dst.cpp -- | FileCheck %s +// +// Test the behaviour of the matching according to the optimal tree edit +// distance, implemented with Zhang and Shasha's algorithm. +// Just for testing we use a tiny value of 10 for maxsize. Subtrees bigger than +// this size will not be processed by the optimal algorithm. + +#ifndef DEST + +void f1() { {;} {{;}} } + +void f2() { {;} {{;;;;;}} } + +void f3() { {;} {{;;;;;;}} } + +#else + +void f1() { +// Jaccard similarity = 3 / (5 + 4 - 3) = 3 / 6 >= 0.5 +// The optimal matching algorithm should move the ; into the outer block +// CHECK: Match CompoundStmt(2) to CompoundStmt(2) +// CHECK-NOT: Match CompoundStmt(3) +// CHECK-NEXT: Match NullStmt(4) to NullStmt(3) + ; {{;}} +} + +void f2() { + // Jaccard similarity = 7 / (10 + 10 - 7) >= 0.5 + // As none of the subtrees is bigger than 10 nodes, the optimal algorithm + // will be run. + // CHECK: Match NullStmt(11) to NullStmt(9) + ;; {{;;;;;}} +} + +void f3() { + // Jaccard similarity = 8 / (11 + 11 - 8) >= 0.5 + // As the subtrees are bigger than 10 nodes, the optimal algorithm will not + // be run. + // CHECK: Delete NullStmt(22) + ;; {{;;;;;;}} +} + +#endif diff --git a/test/Tooling/clang-diff-topdown.cpp b/test/Tooling/clang-diff-topdown.cpp new file mode 100644 index 0000000000000..d6c1d770333ba --- /dev/null +++ b/test/Tooling/clang-diff-topdown.cpp @@ -0,0 +1,83 @@ +// RUN: %clang_cc1 -E %s > %t.src.cpp +// RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST +// RUN: clang-diff -dump-matches -stop-diff-after=topdown %t.src.cpp %t.dst.cpp -- -std=c++11 | FileCheck %s +// +// Test the top-down matching of identical subtrees only. + +#ifndef DEST + +void f1() +{ + // Match some subtree of height greater than 2. + // CHECK: Match CompoundStmt(3) to CompoundStmt(3) + // CHECK: Match CompoundStmt(4) to CompoundStmt(4) + // CHECK: Match NullStmt(5) to NullStmt(5) + {{;}} + + // Don't match subtrees that are smaller. + // CHECK-NOT: Match CompoundStmt(6) + // CHECK-NOT: Match NullStmt(7) + {;} + + // Greedy approach - use the first matching subtree when there are multiple + // identical subtrees. + // CHECK: Match CompoundStmt(8) to CompoundStmt(8) + // CHECK: Match CompoundStmt(9) to CompoundStmt(9) + // CHECK: Match NullStmt(10) to NullStmt(10) + {{;;}} +} + +int x; + +namespace src { + int x; + int x1 = x + 1; + int x2 = ::x + 1; +} + +class A { int x = 1 + 1; void f() { int x1 = x; } }; + +#else + + +void f1() { + + {{;}} + + {;} + + {{;;}} + // CHECK-NOT: Match {{.*}} to CompoundStmt(11) + // CHECK-NOT: Match {{.*}} to CompoundStmt(12) + // CHECK-NOT: Match {{.*}} to NullStmt(13) + {{;;}} + + // CHECK-NOT: Match {{.*}} to NullStmt(14) + ; +} + +int x; + +namespace dst { + int x; + // CHECK: Match DeclRefExpr: :x(17) to DeclRefExpr: :x(22) + int x1 = x + 1; + // CHECK: Match DeclRefExpr: x(21) to DeclRefExpr: x(26) + int x2 = ::x + 1; +} + +class B { + // Only the class name changed; it is not included in the field value, + // therefore there is no update. + // CHECK: Match FieldDecl: :x(int)(24) to FieldDecl: :x(int)(29) + // CHECK-NOT: Update FieldDecl: :x(int)(24) + int x = 1+1; + void f() { + // CHECK: Match MemberExpr: :x(32) to MemberExpr: :x(37) + // CHECK-NOT: Update MemberExpr: :x(32) + int x1 = B::x; + } + +}; + +#endif diff --git a/test/Tooling/fixed-database.cpp b/test/Tooling/fixed-database.cpp new file mode 100644 index 0000000000000..73d0779258b21 --- /dev/null +++ b/test/Tooling/fixed-database.cpp @@ -0,0 +1,19 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t/Src +// RUN: cp "%s" "%t/Src/test.cpp" +// RUN: mkdir -p %t/Include +// RUN: cp "%S/Inputs/fixed-header.h" "%t/Include/" +// -I flag is relative to %t (where compile_flags is), not Src/. +// RUN: echo '-IInclude/' >> %t/compile_flags.txt +// RUN: echo "-Dklazz=class" >> %t/compile_flags.txt +// RUN: echo '-std=c++11' >> %t/compile_flags.txt +// RUN: clang-check "%t/Src/test.cpp" 2>&1 +// RUN: echo > %t/compile_flags.txt +// RUN: not clang-check "%t/Src/test.cpp" 2>&1 | FileCheck "%s" -check-prefix=NODB + +// NODB: unknown type name 'klazz' +klazz F{}; + +// NODB: 'fixed-header.h' file not found +#include "fixed-header.h" +static_assert(SECRET_SYMBOL == 1, ""); |