1//===--- BaseSubobject.h - BaseSubobject class ----------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file provides a definition of the BaseSubobject class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_BASESUBOBJECT_H
15#define LLVM_CLANG_AST_BASESUBOBJECT_H
16
17#include "clang/AST/CharUnits.h"
18#include "llvm/ADT/DenseMap.h"
19#include "llvm/Support/DataTypes.h"
20#include "llvm/Support/type_traits.h"
21
22namespace clang {
23  class CXXRecordDecl;
24
25// BaseSubobject - Uniquely identifies a direct or indirect base class.
26// Stores both the base class decl and the offset from the most derived class to
27// the base class. Used for vtable and VTT generation.
28class BaseSubobject {
29  /// Base - The base class declaration.
30  const CXXRecordDecl *Base;
31
32  /// BaseOffset - The offset from the most derived class to the base class.
33  CharUnits BaseOffset;
34
35public:
36  BaseSubobject() { }
37  BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
38    : Base(Base), BaseOffset(BaseOffset) { }
39
40  /// getBase - Returns the base class declaration.
41  const CXXRecordDecl *getBase() const { return Base; }
42
43  /// getBaseOffset - Returns the base class offset.
44  CharUnits getBaseOffset() const { return BaseOffset; }
45
46  friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
47    return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
48 }
49};
50
51} // end namespace clang
52
53namespace llvm {
54
55template<> struct DenseMapInfo<clang::BaseSubobject> {
56  static clang::BaseSubobject getEmptyKey() {
57    return clang::BaseSubobject(
58      DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
59      clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getEmptyKey()));
60  }
61
62  static clang::BaseSubobject getTombstoneKey() {
63    return clang::BaseSubobject(
64      DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
65      clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getTombstoneKey()));
66  }
67
68  static unsigned getHashValue(const clang::BaseSubobject &Base) {
69    typedef std::pair<const clang::CXXRecordDecl *, clang::CharUnits> PairTy;
70    return DenseMapInfo<PairTy>::getHashValue(PairTy(Base.getBase(),
71                                                     Base.getBaseOffset()));
72  }
73
74  static bool isEqual(const clang::BaseSubobject &LHS,
75                      const clang::BaseSubobject &RHS) {
76    return LHS == RHS;
77  }
78};
79
80// It's OK to treat BaseSubobject as a POD type.
81template <> struct isPodLike<clang::BaseSubobject> {
82  static const bool value = true;
83};
84
85}
86
87#endif
88