brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · b732a44 Raw
173 lines · cpp
1//===- unittests/AST/DataCollectionTest.cpp -------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains tests for the DataCollection module.10//11// They work by hashing the collected data of two nodes and asserting that the12// hash values are equal iff the nodes are considered equal.13//14//===----------------------------------------------------------------------===//15 16#include "clang/AST/DataCollection.h"17#include "clang/AST/DeclTemplate.h"18#include "clang/AST/StmtVisitor.h"19#include "clang/ASTMatchers/ASTMatchFinder.h"20#include "clang/Tooling/Tooling.h"21#include "gtest/gtest.h"22 23using namespace clang;24using namespace tooling;25using namespace ast_matchers;26 27namespace {28class StmtDataCollector : public ConstStmtVisitor<StmtDataCollector> {29  ASTContext &Context;30  llvm::MD5 &DataConsumer;31 32  template <class T> void addData(const T &Data) {33    data_collection::addDataToConsumer(DataConsumer, Data);34  }35 36public:37  StmtDataCollector(const Stmt *S, ASTContext &Context, llvm::MD5 &DataConsumer)38      : Context(Context), DataConsumer(DataConsumer) {39    this->Visit(S);40  }41 42#define DEF_ADD_DATA(CLASS, CODE)                                              \43  template <class Dummy = void> Dummy Visit##CLASS(const CLASS *S) {           \44    CODE;                                                                      \45    ConstStmtVisitor<StmtDataCollector>::Visit##CLASS(S);                      \46  }47 48#include "clang/AST/StmtDataCollectors.inc"49};50} // end anonymous namespace51 52namespace {53struct StmtHashMatch : public MatchFinder::MatchCallback {54  unsigned NumFound;55  llvm::MD5::MD5Result &Hash;56  StmtHashMatch(llvm::MD5::MD5Result &Hash) : NumFound(0), Hash(Hash) {}57 58  void run(const MatchFinder::MatchResult &Result) override {59    const Stmt *S = Result.Nodes.getNodeAs<Stmt>("id");60    if (!S)61      return;62    ++NumFound;63    if (NumFound > 1)64      return;65    llvm::MD5 MD5;66    StmtDataCollector(S, *Result.Context, MD5);67    MD5.final(Hash);68  }69};70} // end anonymous namespace71 72static testing::AssertionResult hashStmt(llvm::MD5::MD5Result &Hash,73                                         const StatementMatcher &StmtMatch,74                                         StringRef Code) {75  StmtHashMatch Hasher(Hash);76  MatchFinder Finder;77  Finder.addMatcher(StmtMatch, &Hasher);78  std::unique_ptr<FrontendActionFactory> Factory(79      newFrontendActionFactory(&Finder));80  if (!runToolOnCode(Factory->create(), Code))81    return testing::AssertionFailure()82           << "Parsing error in \"" << Code.str() << "\"";83  if (Hasher.NumFound == 0)84    return testing::AssertionFailure() << "Matcher didn't find any statements";85  if (Hasher.NumFound > 1)86    return testing::AssertionFailure()87           << "Matcher should match only one statement "88              "(found "89           << Hasher.NumFound << ")";90  return testing::AssertionSuccess();91}92 93static testing::AssertionResult94isStmtHashEqual(const StatementMatcher &StmtMatch, StringRef Code1,95                StringRef Code2) {96  llvm::MD5::MD5Result Hash1, Hash2;97  testing::AssertionResult Result = hashStmt(Hash1, StmtMatch, Code1);98  if (!Result)99    return Result;100  if (!(Result = hashStmt(Hash2, StmtMatch, Code2)))101    return Result;102 103  return testing::AssertionResult(Hash1 == Hash2);104}105 106TEST(StmtDataCollector, TestDeclRefExpr) {107  ASSERT_TRUE(isStmtHashEqual(declRefExpr().bind("id"), "int x, r = x;",108                              "int x, r = x;"));109  ASSERT_FALSE(isStmtHashEqual(declRefExpr().bind("id"), "int x, r = x;",110                               "int y, r = y;"));111  ASSERT_FALSE(isStmtHashEqual(declRefExpr().bind("id"), "int x, r = x;",112                               "namespace n { int x, r = x; };"));113}114 115TEST(StmtDataCollector, TestMemberExpr) {116  ASSERT_TRUE(isStmtHashEqual(memberExpr().bind("id"),117                              "struct { int x; } X; int r = X.x;",118                              "struct { int x; } X; int r = (&X)->x;"));119  ASSERT_TRUE(isStmtHashEqual(memberExpr().bind("id"),120                              "struct { int x; } X; int r = X.x;",121                              "struct { int x; } Y; int r = Y.x;"));122  ASSERT_TRUE(isStmtHashEqual(memberExpr().bind("id"),123                              "struct { int x; } X; int r = X.x;",124                              "struct C { int x; } X; int r = X.C::x;"));125  ASSERT_FALSE(isStmtHashEqual(memberExpr().bind("id"),126                               "struct { int x; } X; int r = X.x;",127                               "struct { int y; } X; int r = X.y;"));128}129 130TEST(StmtDataCollector, TestIntegerLiteral) {131  ASSERT_TRUE(132      isStmtHashEqual(integerLiteral().bind("id"), "int x = 0;", "int x = 0;"));133  ASSERT_TRUE(134      isStmtHashEqual(integerLiteral().bind("id"), "int x = 0;", "int x =00;"));135  ASSERT_FALSE(136      isStmtHashEqual(integerLiteral().bind("id"), "int x = 0;", "int x = 1;"));137}138 139TEST(StmtDataCollector, TestFloatingLiteral) {140  ASSERT_TRUE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .0;",141                              "double x = .0;"));142  ASSERT_TRUE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .10;",143                              "double x = .1;"));144  ASSERT_TRUE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .1;",145                              "double x = 1e-1;"));146  ASSERT_FALSE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .0;",147                               "double x = .1;"));148}149 150TEST(StmtDataCollector, TestStringLiteral) {151  ASSERT_TRUE(isStmtHashEqual(stringLiteral().bind("id"), R"(char x[] = "0";)",152                              R"(char x[] = "0";)"));153  ASSERT_FALSE(isStmtHashEqual(stringLiteral().bind("id"), R"(char x[] = "0";)",154                               R"(char x[] = "1";)"));155}156 157TEST(StmtDataCollector, TestCXXBoolLiteral) {158  ASSERT_TRUE(isStmtHashEqual(cxxBoolLiteral().bind("id"), "bool x = false;",159                              "bool x = false;"));160  ASSERT_FALSE(isStmtHashEqual(cxxBoolLiteral().bind("id"), "bool x = false;",161                               "bool x = true;"));162}163 164TEST(StmtDataCollector, TestCharacterLiteral) {165  ASSERT_TRUE(isStmtHashEqual(characterLiteral().bind("id"), "char x = '0';",166                              "char x = '0';"));167  ASSERT_TRUE(isStmtHashEqual(characterLiteral().bind("id"),168                              R"(char x = '\0';)",169                              R"(char x = '\x00';)"));170  ASSERT_FALSE(isStmtHashEqual(characterLiteral().bind("id"), "char x = '0';",171                               "char x = '1';"));172}173