123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- //===- unittests/AST/DataCollectionTest.cpp -------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file contains tests for the DataCollection module.
- //
- // They work by hashing the collected data of two nodes and asserting that the
- // hash values are equal iff the nodes are considered equal.
- //
- //===----------------------------------------------------------------------===//
- #include "clang/AST/DataCollection.h"
- #include "clang/AST/DeclTemplate.h"
- #include "clang/AST/StmtVisitor.h"
- #include "clang/ASTMatchers/ASTMatchFinder.h"
- #include "clang/Tooling/Tooling.h"
- #include "gtest/gtest.h"
- using namespace clang;
- using namespace tooling;
- using namespace ast_matchers;
- namespace {
- class StmtDataCollector : public ConstStmtVisitor<StmtDataCollector> {
- ASTContext &Context;
- llvm::MD5 &DataConsumer;
- template <class T> void addData(const T &Data) {
- data_collection::addDataToConsumer(DataConsumer, Data);
- }
- public:
- StmtDataCollector(const Stmt *S, ASTContext &Context, llvm::MD5 &DataConsumer)
- : Context(Context), DataConsumer(DataConsumer) {
- this->Visit(S);
- }
- #define DEF_ADD_DATA(CLASS, CODE) \
- template <class Dummy = void> Dummy Visit##CLASS(const CLASS *S) { \
- CODE; \
- ConstStmtVisitor<StmtDataCollector>::Visit##CLASS(S); \
- }
- #include "clang/AST/StmtDataCollectors.inc"
- };
- } // end anonymous namespace
- namespace {
- struct StmtHashMatch : public MatchFinder::MatchCallback {
- unsigned NumFound;
- llvm::MD5::MD5Result &Hash;
- StmtHashMatch(llvm::MD5::MD5Result &Hash) : NumFound(0), Hash(Hash) {}
- void run(const MatchFinder::MatchResult &Result) override {
- const Stmt *S = Result.Nodes.getNodeAs<Stmt>("id");
- if (!S)
- return;
- ++NumFound;
- if (NumFound > 1)
- return;
- llvm::MD5 MD5;
- StmtDataCollector(S, *Result.Context, MD5);
- MD5.final(Hash);
- }
- };
- } // end anonymous namespace
- static testing::AssertionResult hashStmt(llvm::MD5::MD5Result &Hash,
- const StatementMatcher &StmtMatch,
- StringRef Code) {
- StmtHashMatch Hasher(Hash);
- MatchFinder Finder;
- Finder.addMatcher(StmtMatch, &Hasher);
- std::unique_ptr<FrontendActionFactory> Factory(
- newFrontendActionFactory(&Finder));
- if (!runToolOnCode(Factory->create(), Code))
- return testing::AssertionFailure()
- << "Parsing error in \"" << Code.str() << "\"";
- if (Hasher.NumFound == 0)
- return testing::AssertionFailure() << "Matcher didn't find any statements";
- if (Hasher.NumFound > 1)
- return testing::AssertionFailure()
- << "Matcher should match only one statement "
- "(found "
- << Hasher.NumFound << ")";
- return testing::AssertionSuccess();
- }
- static testing::AssertionResult
- isStmtHashEqual(const StatementMatcher &StmtMatch, StringRef Code1,
- StringRef Code2) {
- llvm::MD5::MD5Result Hash1, Hash2;
- testing::AssertionResult Result = hashStmt(Hash1, StmtMatch, Code1);
- if (!Result)
- return Result;
- if (!(Result = hashStmt(Hash2, StmtMatch, Code2)))
- return Result;
- return testing::AssertionResult(Hash1 == Hash2);
- }
- TEST(StmtDataCollector, TestDeclRefExpr) {
- ASSERT_TRUE(isStmtHashEqual(declRefExpr().bind("id"), "int x, r = x;",
- "int x, r = x;"));
- ASSERT_FALSE(isStmtHashEqual(declRefExpr().bind("id"), "int x, r = x;",
- "int y, r = y;"));
- ASSERT_FALSE(isStmtHashEqual(declRefExpr().bind("id"), "int x, r = x;",
- "namespace n { int x, r = x; };"));
- }
- TEST(StmtDataCollector, TestMemberExpr) {
- ASSERT_TRUE(isStmtHashEqual(memberExpr().bind("id"),
- "struct { int x; } X; int r = X.x;",
- "struct { int x; } X; int r = (&X)->x;"));
- ASSERT_TRUE(isStmtHashEqual(memberExpr().bind("id"),
- "struct { int x; } X; int r = X.x;",
- "struct { int x; } Y; int r = Y.x;"));
- ASSERT_TRUE(isStmtHashEqual(memberExpr().bind("id"),
- "struct { int x; } X; int r = X.x;",
- "struct C { int x; } X; int r = X.C::x;"));
- ASSERT_FALSE(isStmtHashEqual(memberExpr().bind("id"),
- "struct { int x; } X; int r = X.x;",
- "struct { int y; } X; int r = X.y;"));
- }
- TEST(StmtDataCollector, TestIntegerLiteral) {
- ASSERT_TRUE(
- isStmtHashEqual(integerLiteral().bind("id"), "int x = 0;", "int x = 0;"));
- ASSERT_TRUE(
- isStmtHashEqual(integerLiteral().bind("id"), "int x = 0;", "int x =00;"));
- ASSERT_FALSE(
- isStmtHashEqual(integerLiteral().bind("id"), "int x = 0;", "int x = 1;"));
- }
- TEST(StmtDataCollector, TestFloatingLiteral) {
- ASSERT_TRUE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .0;",
- "double x = .0;"));
- ASSERT_TRUE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .10;",
- "double x = .1;"));
- ASSERT_TRUE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .1;",
- "double x = 1e-1;"));
- ASSERT_FALSE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .0;",
- "double x = .1;"));
- }
- TEST(StmtDataCollector, TestStringLiteral) {
- ASSERT_TRUE(isStmtHashEqual(stringLiteral().bind("id"), R"(char x[] = "0";)",
- R"(char x[] = "0";)"));
- ASSERT_FALSE(isStmtHashEqual(stringLiteral().bind("id"), R"(char x[] = "0";)",
- R"(char x[] = "1";)"));
- }
- TEST(StmtDataCollector, TestCXXBoolLiteral) {
- ASSERT_TRUE(isStmtHashEqual(cxxBoolLiteral().bind("id"), "bool x = false;",
- "bool x = false;"));
- ASSERT_FALSE(isStmtHashEqual(cxxBoolLiteral().bind("id"), "bool x = false;",
- "bool x = true;"));
- }
- TEST(StmtDataCollector, TestCharacterLiteral) {
- ASSERT_TRUE(isStmtHashEqual(characterLiteral().bind("id"), "char x = '0';",
- "char x = '0';"));
- ASSERT_TRUE(isStmtHashEqual(characterLiteral().bind("id"),
- R"(char x = '\0';)",
- R"(char x = '\x00';)"));
- ASSERT_FALSE(isStmtHashEqual(characterLiteral().bind("id"), "char x = '0';",
- "char x = '1';"));
- }
|