141aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek//===- unittest/ADT/IntrusiveRefCntPtrTest.cpp ----------------------------===//
241aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek//
341aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek//                     The LLVM Compiler Infrastructure
441aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek//
541aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek// This file is distributed under the University of Illinois Open Source
641aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek// License. See LICENSE.TXT for details.
741aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek//
841aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek//===----------------------------------------------------------------------===//
941aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek
1041aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek#include "llvm/ADT/IntrusiveRefCntPtr.h"
1141aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek#include "gtest/gtest.h"
1241aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek
1341aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimeknamespace llvm {
1441aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek
1541aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimekstruct VirtualRefCounted : public RefCountedBaseVPTR {
1641aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  virtual void f() {}
1741aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek};
1841aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek
1941aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek// Run this test with valgrind to detect memory leaks.
2041aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel KlimekTEST(IntrusiveRefCntPtr, RefCountedBaseVPTRCopyDoesNotLeak) {
2141aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  VirtualRefCounted *V1 = new VirtualRefCounted;
2241aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  IntrusiveRefCntPtr<VirtualRefCounted> R1 = V1;
2341aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  VirtualRefCounted *V2 = new VirtualRefCounted(*V1);
2441aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  IntrusiveRefCntPtr<VirtualRefCounted> R2 = V2;
2541aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek}
2641aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek
2741aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimekstruct SimpleRefCounted : public RefCountedBase<SimpleRefCounted> {};
2841aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek
2941aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek// Run this test with valgrind to detect memory leaks.
3041aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel KlimekTEST(IntrusiveRefCntPtr, RefCountedBaseCopyDoesNotLeak) {
3141aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  SimpleRefCounted *S1 = new SimpleRefCounted;
3241aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  IntrusiveRefCntPtr<SimpleRefCounted> R1 = S1;
3341aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  SimpleRefCounted *S2 = new SimpleRefCounted(*S1);
3441aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  IntrusiveRefCntPtr<SimpleRefCounted> R2 = S2;
3541aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek}
3641aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek
3741aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimekstruct InterceptRefCounted : public RefCountedBase<InterceptRefCounted> {
3841aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  InterceptRefCounted(bool *Released, bool *Retained)
3941aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek    : Released(Released), Retained(Retained) {}
4041aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  bool * const Released;
4141aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  bool * const Retained;
4241aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek};
4341aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimektemplate <> struct IntrusiveRefCntPtrInfo<InterceptRefCounted> {
4441aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  static void retain(InterceptRefCounted *I) {
4541aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek    *I->Retained = true;
4641aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek    I->Retain();
4741aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  }
4841aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  static void release(InterceptRefCounted *I) {
4941aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek    *I->Released = true;
5041aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek    I->Release();
5141aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  }
5241aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek};
5341aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel KlimekTEST(IntrusiveRefCntPtr, UsesTraitsToRetainAndRelease) {
5441aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  bool Released = false;
5541aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  bool Retained = false;
5641aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  {
5741aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek    InterceptRefCounted *I = new InterceptRefCounted(&Released, &Retained);
5841aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek    IntrusiveRefCntPtr<InterceptRefCounted> R = I;
5941aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  }
6041aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  EXPECT_TRUE(Released);
6141aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek  EXPECT_TRUE(Retained);
6241aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek}
6341aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek
6441aa108f743ed3b97cdf060ae25cfef38af5bc9eManuel Klimek} // end namespace llvm
65