Visit lambda capture inits from RecursiveASTVisitor::TraverseLambdaCapture().
Summary:
rL277342 made RecursiveASTVisitor visit lambda capture initialization
expressions (these are the Exprs in LambdaExpr::capture_inits()).
jdennett identified two issues with rL277342 (see comments there for details):
- It visits initialization expressions for implicit lambda captures, even if
shouldVisitImplicitCode() returns false.
- It visits initialization expressions for init captures twice (because these
were already traveresed in TraverseLambdaCapture() before rL277342)
This patch fixes these issues and moves the code for traversing initialization
expressions into TraverseLambdaCapture().
This patch also makes two changes required for the tests:
- It adds Lang_CXX14 to the Language enum in TestVisitor.
- It adds a parameter to ExpectedLocationVisitor::ExpectMatch() that specifies
the number of times a match is expected to be seen.
Reviewers: klimek, jdennett, alexfh
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D23204
llvm-svn: 278933
diff --git a/clang/unittests/Tooling/TestVisitor.h b/clang/unittests/Tooling/TestVisitor.h
index f4a0039..a762ec8 100644
--- a/clang/unittests/Tooling/TestVisitor.h
+++ b/clang/unittests/Tooling/TestVisitor.h
@@ -43,6 +43,7 @@
Lang_C,
Lang_CXX98,
Lang_CXX11,
+ Lang_CXX14,
Lang_OBJC,
Lang_OBJCXX11,
Lang_CXX = Lang_CXX98
@@ -55,6 +56,7 @@
case Lang_C: Args.push_back("-std=c99"); break;
case Lang_CXX98: Args.push_back("-std=c++98"); break;
case Lang_CXX11: Args.push_back("-std=c++11"); break;
+ case Lang_CXX14: Args.push_back("-std=c++14"); break;
case Lang_OBJC: Args.push_back("-ObjC"); break;
case Lang_OBJCXX11:
Args.push_back("-ObjC++");
@@ -127,9 +129,12 @@
/// \brief Expect 'Match' to occur at the given 'Line' and 'Column'.
///
/// Any number of expected matches can be set by calling this repeatedly.
- /// Each is expected to be matched exactly once.
- void ExpectMatch(Twine Match, unsigned Line, unsigned Column) {
- ExpectedMatches.push_back(ExpectedMatch(Match, Line, Column));
+ /// Each is expected to be matched 'Times' number of times. (This is useful in
+ /// cases in which different AST nodes can match at the same source code
+ /// location.)
+ void ExpectMatch(Twine Match, unsigned Line, unsigned Column,
+ unsigned Times = 1) {
+ ExpectedMatches.push_back(ExpectedMatch(Match, Line, Column, Times));
}
/// \brief Checks that all expected matches have been found.
@@ -200,14 +205,17 @@
};
struct ExpectedMatch {
- ExpectedMatch(Twine Name, unsigned LineNumber, unsigned ColumnNumber)
- : Candidate(Name, LineNumber, ColumnNumber), Found(false) {}
+ ExpectedMatch(Twine Name, unsigned LineNumber, unsigned ColumnNumber,
+ unsigned Times)
+ : Candidate(Name, LineNumber, ColumnNumber), TimesExpected(Times),
+ TimesSeen(0) {}
void UpdateFor(StringRef Name, FullSourceLoc Location, SourceManager &SM) {
if (Candidate.Matches(Name, Location)) {
- EXPECT_TRUE(!Found);
- Found = true;
- } else if (!Found && Candidate.PartiallyMatches(Name, Location)) {
+ EXPECT_LT(TimesSeen, TimesExpected);
+ ++TimesSeen;
+ } else if (TimesSeen < TimesExpected &&
+ Candidate.PartiallyMatches(Name, Location)) {
llvm::raw_string_ostream Stream(PartialMatches);
Stream << ", partial match: \"" << Name << "\" at ";
Location.print(Stream, SM);
@@ -215,7 +223,7 @@
}
void ExpectFound() const {
- EXPECT_TRUE(Found)
+ EXPECT_EQ(TimesExpected, TimesSeen)
<< "Expected \"" << Candidate.ExpectedName
<< "\" at " << Candidate.LineNumber
<< ":" << Candidate.ColumnNumber << PartialMatches;
@@ -223,7 +231,8 @@
MatchCandidate Candidate;
std::string PartialMatches;
- bool Found;
+ unsigned TimesExpected;
+ unsigned TimesSeen;
};
std::vector<MatchCandidate> DisallowedMatches;