aboutsummaryrefslogtreecommitdiff
path: root/clang/unittests/Tooling/TransformerTest.cpp
diff options
context:
space:
mode:
authorYitzhak Mandelbaum <yitzhakm@google.com>2019-09-27 15:26:04 +0000
committerYitzhak Mandelbaum <yitzhakm@google.com>2019-09-27 15:26:04 +0000
commitdb24ef509ecb271a1b03c35c34889f539bc70a32 (patch)
treeddb9f298bd71bfd6b80d136a4a477626caa8d552 /clang/unittests/Tooling/TransformerTest.cpp
parent59e26308e60a08a5a4534ba827744564c71d7aff (diff)
downloadllvm-db24ef509ecb271a1b03c35c34889f539bc70a32.zip
llvm-db24ef509ecb271a1b03c35c34889f539bc70a32.tar.gz
llvm-db24ef509ecb271a1b03c35c34889f539bc70a32.tar.bz2
[libTooling] Transformer: refine `SourceLocation` specified as anchor of changes.
Summary: Every change triggered by a rewrite rule is anchored at a particular location in the source code. This patch refines how that location is chosen and defines it as an explicit function so it can be shared by other Transformer implementations. This patch was inspired by a bug found by a clang tidy, wherein two changes were anchored at the same location (the expansion loc of the macro) resulting in the discarding of the second change. Reviewers: gribozavr Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D66652 llvm-svn: 373093
Diffstat (limited to 'clang/unittests/Tooling/TransformerTest.cpp')
-rw-r--r--clang/unittests/Tooling/TransformerTest.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/clang/unittests/Tooling/TransformerTest.cpp b/clang/unittests/Tooling/TransformerTest.cpp
index 554e586..5d55182 100644
--- a/clang/unittests/Tooling/TransformerTest.cpp
+++ b/clang/unittests/Tooling/TransformerTest.cpp
@@ -710,6 +710,57 @@ TEST_F(TransformerTest, IdentityMacro) {
testRule(ruleStrlenSize(), Input, Expected);
}
+// Tests that two changes in a single macro expansion do not lead to conflicts
+// in applying the changes.
+TEST_F(TransformerTest, TwoChangesInOneMacroExpansion) {
+ std::string Input = R"cc(
+#define PLUS(a,b) (a) + (b)
+ int f() { return PLUS(3, 4); }
+ )cc";
+ std::string Expected = R"cc(
+#define PLUS(a,b) (a) + (b)
+ int f() { return PLUS(LIT, LIT); }
+ )cc";
+
+ testRule(makeRule(integerLiteral(), change(text("LIT"))), Input, Expected);
+}
+
+// Tests case where the rule's match spans both source from the macro and its
+// arg, with the begin location (the "anchor") being the arg.
+TEST_F(TransformerTest, MatchSpansMacroTextButChangeDoesNot) {
+ std::string Input = R"cc(
+#define PLUS_ONE(a) a + 1
+ int f() { return PLUS_ONE(3); }
+ )cc";
+ std::string Expected = R"cc(
+#define PLUS_ONE(a) a + 1
+ int f() { return PLUS_ONE(LIT); }
+ )cc";
+
+ StringRef E = "expr";
+ testRule(makeRule(binaryOperator(hasLHS(expr().bind(E))),
+ change(node(E), text("LIT"))),
+ Input, Expected);
+}
+
+// Tests case where the rule's match spans both source from the macro and its
+// arg, with the begin location (the "anchor") being inside the macro.
+TEST_F(TransformerTest, MatchSpansMacroTextButChangeDoesNotAnchoredInMacro) {
+ std::string Input = R"cc(
+#define PLUS_ONE(a) 1 + a
+ int f() { return PLUS_ONE(3); }
+ )cc";
+ std::string Expected = R"cc(
+#define PLUS_ONE(a) 1 + a
+ int f() { return PLUS_ONE(LIT); }
+ )cc";
+
+ StringRef E = "expr";
+ testRule(makeRule(binaryOperator(hasRHS(expr().bind(E))),
+ change(node(E), text("LIT"))),
+ Input, Expected);
+}
+
// No rewrite is applied when the changed text does not encompass the entirety
// of the expanded text. That is, the edit would have to be applied to the
// macro's definition to succeed and editing the expansion point would not