r174057 - Move commonly useful code for AST testing into MatchVerfier.h.
Manuel Klimek
klimek at google.com
Thu Jan 31 05:10:41 PST 2013
Author: klimek
Date: Thu Jan 31 07:10:40 2013
New Revision: 174057
URL: http://llvm.org/viewvc/llvm-project?rev=174057&view=rev
Log:
Move commonly useful code for AST testing into MatchVerfier.h.
Added:
cfe/trunk/unittests/AST/MatchVerifier.h
- copied, changed from r174055, cfe/trunk/unittests/AST/SourceLocationTest.cpp
Modified:
cfe/trunk/unittests/AST/SourceLocationTest.cpp
Copied: cfe/trunk/unittests/AST/MatchVerifier.h (from r174055, cfe/trunk/unittests/AST/SourceLocationTest.cpp)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/MatchVerifier.h?p2=cfe/trunk/unittests/AST/MatchVerifier.h&p1=cfe/trunk/unittests/AST/SourceLocationTest.cpp&r1=174055&r2=174057&rev=174057&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/SourceLocationTest.cpp (original)
+++ cfe/trunk/unittests/AST/MatchVerifier.h Thu Jan 31 07:10:40 2013
@@ -1,4 +1,4 @@
-//===- unittest/AST/SourceLocationTest.cpp - AST source loc unit tests ----===//
+//===- unittest/AST/MatchVerifier.h - AST unit test support ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains tests for SourceLocation and SourceRange fields
-// in AST nodes.
+// Provides MatchVerifier, a base class to implement gtest matchers that
+// verify things that can be matched on the AST.
//
-// FIXME: In the long-term, when we test more than source locations, we may
-// want to have a unit test file for an AST node (or group of related nodes),
-// rather than a unit test file for source locations for all AST nodes.
+// Also implements matchers based on MatchVerifier:
+// LocationVerifier and RangeVerifier to verify whether a matched node has
+// the expected source location or source range.
//
//===----------------------------------------------------------------------===//
@@ -25,15 +25,9 @@
namespace clang {
namespace ast_matchers {
-using clang::tooling::newFrontendActionFactory;
-using clang::tooling::runToolOnCodeWithArgs;
-using clang::tooling::FrontendActionFactory;
-
enum Language { Lang_C, Lang_C89, Lang_CXX };
/// \brief Base class for verifying some property of nodes found by a matcher.
-///
-/// FIXME: This class should be shared with other AST tests.
template <typename NodeType>
class MatchVerifier : public MatchFinder::MatchCallback {
public:
@@ -57,6 +51,10 @@ protected:
VerifyResult = Result.str();
}
+ void setSuccess() {
+ Verified = true;
+ }
+
private:
bool Verified;
std::string VerifyResult;
@@ -69,7 +67,8 @@ testing::AssertionResult MatchVerifier<N
const std::string &Code, const MatcherType &AMatcher, Language L) {
MatchFinder Finder;
Finder.addMatcher(AMatcher.bind(""), this);
- OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
+ OwningPtr<tooling::FrontendActionFactory> Factory(
+ tooling::newFrontendActionFactory(&Finder));
std::vector<std::string> Args;
StringRef FileName;
@@ -90,7 +89,7 @@ testing::AssertionResult MatchVerifier<N
// Default to failure in case callback is never called
setFailure("Could not find match");
- if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
+ if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
return testing::AssertionFailure() << "Parsing error";
if (!Verified)
return testing::AssertionFailure() << VerifyResult;
@@ -103,8 +102,8 @@ void MatchVerifier<NodeType>::run(const
if (!Node) {
setFailure("Matched node has wrong type");
} else {
- // Callback has been called, default to success
- Verified = true;
+ // Callback has been called, default to success.
+ setSuccess();
verify(Result, *Node);
}
}
@@ -191,99 +190,5 @@ private:
unsigned ExpectBeginLine, ExpectBeginColumn, ExpectEndLine, ExpectEndColumn;
};
-TEST(MatchVerifier, ParseError) {
- LocationVerifier<VarDecl> Verifier;
- Verifier.expectLocation(1, 1);
- EXPECT_FALSE(Verifier.match("int i", varDecl()));
-}
-
-TEST(MatchVerifier, NoMatch) {
- LocationVerifier<VarDecl> Verifier;
- Verifier.expectLocation(1, 1);
- EXPECT_FALSE(Verifier.match("int i;", recordDecl()));
-}
-
-TEST(MatchVerifier, WrongType) {
- LocationVerifier<RecordDecl> Verifier;
- Verifier.expectLocation(1, 1);
- EXPECT_FALSE(Verifier.match("int i;", varDecl()));
-}
-
-TEST(LocationVerifier, WrongLocation) {
- LocationVerifier<VarDecl> Verifier;
- Verifier.expectLocation(1, 1);
- EXPECT_FALSE(Verifier.match("int i;", varDecl()));
-}
-
-TEST(RangeVerifier, WrongRange) {
- RangeVerifier<VarDecl> Verifier;
- Verifier.expectRange(1, 1, 1, 1);
- EXPECT_FALSE(Verifier.match("int i;", varDecl()));
-}
-
-class LabelDeclRangeVerifier : public RangeVerifier<LabelStmt> {
-protected:
- virtual SourceRange getRange(const LabelStmt &Node) {
- return Node.getDecl()->getSourceRange();
- }
-};
-
-TEST(LabelDecl, Range) {
- LabelDeclRangeVerifier Verifier;
- Verifier.expectRange(1, 12, 1, 12);
- EXPECT_TRUE(Verifier.match("void f() { l: return; }", labelStmt()));
-}
-
-TEST(LabelStmt, Range) {
- RangeVerifier<LabelStmt> Verifier;
- Verifier.expectRange(1, 12, 1, 15);
- EXPECT_TRUE(Verifier.match("void f() { l: return; }", labelStmt()));
-}
-
-TEST(ParmVarDecl, KNRLocation) {
- LocationVerifier<ParmVarDecl> Verifier;
- Verifier.expectLocation(1, 8);
- EXPECT_TRUE(Verifier.match("void f(i) {}", varDecl(), Lang_C));
-}
-
-TEST(ParmVarDecl, KNRRange) {
- RangeVerifier<ParmVarDecl> Verifier;
- Verifier.expectRange(1, 8, 1, 8);
- EXPECT_TRUE(Verifier.match("void f(i) {}", varDecl(), Lang_C));
-}
-
-TEST(CXXNewExpr, ArrayRange) {
- RangeVerifier<CXXNewExpr> Verifier;
- Verifier.expectRange(1, 12, 1, 22);
- EXPECT_TRUE(Verifier.match("void f() { new int[10]; }", newExpr()));
-}
-
-TEST(CXXNewExpr, ParenRange) {
- RangeVerifier<CXXNewExpr> Verifier;
- Verifier.expectRange(1, 12, 1, 20);
- EXPECT_TRUE(Verifier.match("void f() { new int(); }", newExpr()));
-}
-
-TEST(MemberExpr, ImplicitMemberRange) {
- RangeVerifier<MemberExpr> Verifier;
- Verifier.expectRange(2, 30, 2, 30);
- EXPECT_TRUE(Verifier.match("struct S { operator int() const; };\n"
- "int foo(const S& s) { return s; }",
- memberExpr()));
-}
-
-TEST(VarDecl, VMTypeFixedVarDeclRange) {
- RangeVerifier<VarDecl> Verifier;
- Verifier.expectRange(1, 1, 1, 23);
- EXPECT_TRUE(Verifier.match("int a[(int)(void*)1234];",
- varDecl(), Lang_C89));
-}
-
-TEST(CXXConstructorDecl, NoRetFunTypeLocRange) {
- RangeVerifier<CXXConstructorDecl> Verifier;
- Verifier.expectRange(1, 11, 1, 13);
- EXPECT_TRUE(Verifier.match("class C { C(); };", functionDecl()));
-}
-
} // end namespace ast_matchers
} // end namespace clang
Modified: cfe/trunk/unittests/AST/SourceLocationTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/SourceLocationTest.cpp?rev=174057&r1=174056&r2=174057&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/SourceLocationTest.cpp (original)
+++ cfe/trunk/unittests/AST/SourceLocationTest.cpp Thu Jan 31 07:10:40 2013
@@ -21,175 +21,12 @@
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"
+#include "MatchVerifier.h"
namespace clang {
namespace ast_matchers {
-using clang::tooling::newFrontendActionFactory;
-using clang::tooling::runToolOnCodeWithArgs;
-using clang::tooling::FrontendActionFactory;
-
-enum Language { Lang_C, Lang_C89, Lang_CXX };
-
-/// \brief Base class for verifying some property of nodes found by a matcher.
-///
-/// FIXME: This class should be shared with other AST tests.
-template <typename NodeType>
-class MatchVerifier : public MatchFinder::MatchCallback {
-public:
- template <typename MatcherType>
- testing::AssertionResult match(const std::string &Code,
- const MatcherType &AMatcher) {
- return match(Code, AMatcher, Lang_CXX);
- }
-
- template <typename MatcherType>
- testing::AssertionResult match(const std::string &Code,
- const MatcherType &AMatcher, Language L);
-
-protected:
- virtual void run(const MatchFinder::MatchResult &Result);
- virtual void verify(const MatchFinder::MatchResult &Result,
- const NodeType &Node) = 0;
-
- void setFailure(const Twine &Result) {
- Verified = false;
- VerifyResult = Result.str();
- }
-
-private:
- bool Verified;
- std::string VerifyResult;
-};
-
-/// \brief Runs a matcher over some code, and returns the result of the
-/// verifier for the matched node.
-template <typename NodeType> template <typename MatcherType>
-testing::AssertionResult MatchVerifier<NodeType>::match(
- const std::string &Code, const MatcherType &AMatcher, Language L) {
- MatchFinder Finder;
- Finder.addMatcher(AMatcher.bind(""), this);
- OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
-
- std::vector<std::string> Args;
- StringRef FileName;
- switch (L) {
- case Lang_C:
- Args.push_back("-std=c99");
- FileName = "input.c";
- break;
- case Lang_C89:
- Args.push_back("-std=c89");
- FileName = "input.c";
- break;
- case Lang_CXX:
- Args.push_back("-std=c++98");
- FileName = "input.cc";
- break;
- }
-
- // Default to failure in case callback is never called
- setFailure("Could not find match");
- if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
- return testing::AssertionFailure() << "Parsing error";
- if (!Verified)
- return testing::AssertionFailure() << VerifyResult;
- return testing::AssertionSuccess();
-}
-
-template <typename NodeType>
-void MatchVerifier<NodeType>::run(const MatchFinder::MatchResult &Result) {
- const NodeType *Node = Result.Nodes.getNodeAs<NodeType>("");
- if (!Node) {
- setFailure("Matched node has wrong type");
- } else {
- // Callback has been called, default to success
- Verified = true;
- verify(Result, *Node);
- }
-}
-
-/// \brief Verify whether a node has the correct source location.
-///
-/// By default, Node.getSourceLocation() is checked. This can be changed
-/// by overriding getLocation().
-template <typename NodeType>
-class LocationVerifier : public MatchVerifier<NodeType> {
-public:
- void expectLocation(unsigned Line, unsigned Column) {
- ExpectLine = Line;
- ExpectColumn = Column;
- }
-
-protected:
- void verify(const MatchFinder::MatchResult &Result, const NodeType &Node) {
- SourceLocation Loc = getLocation(Node);
- unsigned Line = Result.SourceManager->getSpellingLineNumber(Loc);
- unsigned Column = Result.SourceManager->getSpellingColumnNumber(Loc);
- if (Line != ExpectLine || Column != ExpectColumn) {
- std::string MsgStr;
- llvm::raw_string_ostream Msg(MsgStr);
- Msg << "Expected location <" << ExpectLine << ":" << ExpectColumn
- << ">, found <";
- Loc.print(Msg, *Result.SourceManager);
- Msg << '>';
- this->setFailure(Msg.str());
- }
- }
-
- virtual SourceLocation getLocation(const NodeType &Node) {
- return Node.getLocation();
- }
-
-private:
- unsigned ExpectLine, ExpectColumn;
-};
-
-/// \brief Verify whether a node has the correct source range.
-///
-/// By default, Node.getSourceRange() is checked. This can be changed
-/// by overriding getRange().
-template <typename NodeType>
-class RangeVerifier : public MatchVerifier<NodeType> {
-public:
- void expectRange(unsigned BeginLine, unsigned BeginColumn,
- unsigned EndLine, unsigned EndColumn) {
- ExpectBeginLine = BeginLine;
- ExpectBeginColumn = BeginColumn;
- ExpectEndLine = EndLine;
- ExpectEndColumn = EndColumn;
- }
-
-protected:
- void verify(const MatchFinder::MatchResult &Result, const NodeType &Node) {
- SourceRange R = getRange(Node);
- SourceLocation Begin = R.getBegin();
- SourceLocation End = R.getEnd();
- unsigned BeginLine = Result.SourceManager->getSpellingLineNumber(Begin);
- unsigned BeginColumn = Result.SourceManager->getSpellingColumnNumber(Begin);
- unsigned EndLine = Result.SourceManager->getSpellingLineNumber(End);
- unsigned EndColumn = Result.SourceManager->getSpellingColumnNumber(End);
- if (BeginLine != ExpectBeginLine || BeginColumn != ExpectBeginColumn ||
- EndLine != ExpectEndLine || EndColumn != ExpectEndColumn) {
- std::string MsgStr;
- llvm::raw_string_ostream Msg(MsgStr);
- Msg << "Expected range <" << ExpectBeginLine << ":" << ExpectBeginColumn
- << '-' << ExpectEndLine << ":" << ExpectEndColumn << ">, found <";
- Begin.print(Msg, *Result.SourceManager);
- Msg << '-';
- End.print(Msg, *Result.SourceManager);
- Msg << '>';
- this->setFailure(Msg.str());
- }
- }
-
- virtual SourceRange getRange(const NodeType &Node) {
- return Node.getSourceRange();
- }
-
-private:
- unsigned ExpectBeginLine, ExpectBeginColumn, ExpectEndLine, ExpectEndColumn;
-};
+// FIXME: Pull the *Verifier tests into their own test file.
TEST(MatchVerifier, ParseError) {
LocationVerifier<VarDecl> Verifier;
More information about the cfe-commits
mailing list