//===- unittests/StaticAnalyzer/ParamRegionTest.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
//
//===----------------------------------------------------------------------===//

#include "Reusables.h"

#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"

namespace clang {
namespace ento {
namespace {

class ParamRegionTestConsumer : public ExprEngineConsumer {
  void checkForSameParamRegions(MemRegionManager &MRMgr,
                                const StackFrameContext *SFC,
                                const ParmVarDecl *PVD) {
    ASSERT_TRUE(llvm::all_of(PVD->redecls(), [&](const clang::VarDecl *D2) {
      return MRMgr.getVarRegion(PVD, SFC) ==
             MRMgr.getVarRegion(cast<ParmVarDecl>(D2), SFC);
    }));
  }

  void performTest(const Decl *D) {
    StoreManager &StMgr = Eng.getStoreManager();
    MemRegionManager &MRMgr = StMgr.getRegionManager();
    const StackFrameContext *SFC =
        Eng.getAnalysisDeclContextManager().getStackFrame(D);

    if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
      for (const auto *P : FD->parameters()) {
        if (SFC->inTopFrame())
          assert(isa<NonParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
        else
          assert(isa<ParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
        checkForSameParamRegions(MRMgr, SFC, P);
      }
    } else if (const auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
      for (const auto *P : CD->parameters()) {
        if (SFC->inTopFrame())
          assert(isa<NonParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
        else
          assert(isa<ParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
        checkForSameParamRegions(MRMgr, SFC, P);
      }
    } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
      for (const auto *P : MD->parameters()) {
        if (SFC->inTopFrame())
          assert(isa<NonParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
        else
          assert(isa<ParamVarRegion>(MRMgr.getVarRegion(P, SFC)));
        checkForSameParamRegions(MRMgr, SFC, P);
      }
    }
  }

public:
  ParamRegionTestConsumer(CompilerInstance &C) : ExprEngineConsumer(C) {}

  bool HandleTopLevelDecl(DeclGroupRef DG) override {
    for (const auto *D : DG) {
      performTest(D);
    }
    return true;
  }
};

class ParamRegionTestAction : public ASTFrontendAction {
public:
  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
                                                 StringRef File) override {
    return std::make_unique<ParamRegionTestConsumer>(Compiler);
  }
};

TEST(ParamRegion, ParamRegionTest) {
  EXPECT_TRUE(
      tooling::runToolOnCode(std::make_unique<ParamRegionTestAction>(),
                             R"(void foo(int n);
                                void baz(int p);

                                void foo(int n) {
                                  auto lambda = [n](int m) {
                                    return n + m;
                                  };

                                  int k = lambda(2);
                                }

                                void bar(int l) {
                                  foo(l);
                                }

                                struct S {
                                  int n;
                                  S(int nn): n(nn) {}
                                };

                                void baz(int p) {
                                  S s(p);
                                }

                                void bar(int l);
                                void baz(int p);)"));
  EXPECT_TRUE(
      tooling::runToolOnCode(std::make_unique<ParamRegionTestAction>(),
                             R"(@interface O
                                + alloc;
                                - initWithInt:(int)q;
                                @end

                                void qix(int r) {
                                  O *o = [[O alloc] initWithInt:r];
                                })",
                             "input.m"));
}

} // namespace
} // namespace ento
} // namespace clang
