// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "lifetime_analysis/points_to_map.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "lifetime_annotations/lifetime.h"
#include "lifetime_annotations/test/run_on_code.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

namespace clang {
namespace tidy {
namespace lifetimes {
namespace {

const clang::CallExpr* getFirstCallExpr(const clang::ASTContext& ast_context) {
  using clang::ast_matchers::callExpr;
  using clang::ast_matchers::match;
  using clang::ast_matchers::selectFirst;

  return selectFirst<clang::CallExpr>(
      "call", match(callExpr().bind("call"),
                    const_cast<clang::ASTContext&>(ast_context)));
}

TEST(PointsToMapTest, Equality) {
  runOnCodeWithLifetimeHandlers(
      "int *return_int_ptr();"
      "int* p = return_int_ptr();",
      [](const clang::ASTContext& ast_context,
         const LifetimeAnnotationContext&) {
        Object p1(Lifetime::CreateLocal(), ast_context.IntTy);
        Object p2(Lifetime::CreateLocal(), ast_context.IntTy);
        Object p3(Lifetime::CreateLocal(), ast_context.IntTy);
        const clang::CallExpr* expr = getFirstCallExpr(ast_context);

        {
          PointsToMap map1, map2;
          map1.SetPointerPointsToSet(&p1, {&p2});
          map2.SetPointerPointsToSet(&p1, {&p3});
          EXPECT_EQ(map1, PointsToMap(map1));
          EXPECT_NE(map1, PointsToMap());
          EXPECT_NE(map1, map2);
        }

        {
          PointsToMap map1, map2;
          map1.SetExprObjectSet(expr, {&p1});
          map2.SetExprObjectSet(expr, {&p2});
          EXPECT_EQ(map1, PointsToMap(map1));
          EXPECT_NE(map1, PointsToMap());
          EXPECT_NE(map1, map2);
        }
      },
      {});
}

TEST(PointsToMapTest, Union) {
  runOnCodeWithLifetimeHandlers(
      "int *return_int_ptr();"
      "int* p = return_int_ptr();",
      [](const clang::ASTContext& ast_context,
         const LifetimeAnnotationContext&) {
        Object p1(Lifetime::CreateLocal(), ast_context.IntTy);
        Object p2(Lifetime::CreateLocal(), ast_context.IntTy);
        Object p3(Lifetime::CreateLocal(), ast_context.IntTy);
        const clang::CallExpr* expr = getFirstCallExpr(ast_context);

        PointsToMap map1, map2;
        map1.SetPointerPointsToSet(&p1, {&p2});
        map2.SetPointerPointsToSet(&p1, {&p3});

        map1.SetExprObjectSet(expr, {&p2});
        map2.SetExprObjectSet(expr, {&p3});

        PointsToMap union_map = map1.Union(map2);

        EXPECT_EQ(union_map.GetPointerPointsToSet(&p1), ObjectSet({&p2, &p3}));
        EXPECT_EQ(union_map.GetExprObjectSet(expr), ObjectSet({&p2, &p3}));
      },
      {});
}

TEST(PointsToMapTest, GetPointerPointsToSet) {
  runOnCodeWithLifetimeHandlers(
      "",
      [](const clang::ASTContext& ast_context,
         const LifetimeAnnotationContext&) {
        Object p1(Lifetime::CreateLocal(), ast_context.IntTy);
        Object p2(Lifetime::CreateLocal(), ast_context.IntTy);
        Object p3(Lifetime::CreateLocal(), ast_context.IntTy);
        Object p4(Lifetime::CreateLocal(), ast_context.IntTy);

        PointsToMap map;

        EXPECT_EQ(map.GetPointerPointsToSet(&p1), ObjectSet());

        map.SetPointerPointsToSet(&p1, {&p3});
        map.SetPointerPointsToSet(&p2, {&p4});

        EXPECT_EQ(map.GetPointerPointsToSet(&p1), ObjectSet({&p3}));
        EXPECT_EQ(map.GetPointerPointsToSet({&p1, &p2}), ObjectSet({&p3, &p4}));
      },
      {});
}

TEST(PointsToMapTest, ExtendPointerPointsToSet) {
  runOnCodeWithLifetimeHandlers(
      "",
      [](const clang::ASTContext& ast_context,
         const LifetimeAnnotationContext&) {
        Object p1(Lifetime::CreateLocal(), ast_context.IntTy);
        Object p2(Lifetime::CreateLocal(), ast_context.IntTy);
        Object p3(Lifetime::CreateLocal(), ast_context.IntTy);

        PointsToMap map;

        EXPECT_EQ(map.GetPointerPointsToSet(&p1), ObjectSet());

        map.ExtendPointerPointsToSet(&p1, {&p2});

        EXPECT_EQ(map.GetPointerPointsToSet(&p1), ObjectSet({&p2}));

        map.ExtendPointerPointsToSet(&p1, {&p3});

        EXPECT_EQ(map.GetPointerPointsToSet(&p1), ObjectSet({&p2, &p3}));
      },
      {});
}

TEST(PointsToMapTest, GetExprObjectSet) {
  runOnCodeWithLifetimeHandlers(
      "int *return_int_ptr();"
      "int* p = return_int_ptr();",
      [](const clang::ASTContext& ast_context,
         const LifetimeAnnotationContext&) {
        Object p1(Lifetime::CreateLocal(), ast_context.IntTy);
        const clang::CallExpr* expr = getFirstCallExpr(ast_context);

        PointsToMap map;

        map.SetExprObjectSet(expr, {&p1});
        EXPECT_EQ(map.GetExprObjectSet(expr), ObjectSet({&p1}));
      },
      {});
}

}  // namespace
}  // namespace lifetimes
}  // namespace tidy
}  // namespace clang
