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 "clang/AST/DeclCXX.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/Support/DataTypes.h"
21#include "llvm/Support/type_traits.h"
22
23namespace clang {
24// BaseSubobject - Uniquely identifies a direct or indirect base class.
25// Stores both the base class decl and the offset from the most derived class to
26// the base class. Used for vtable and VTT generation.
27class BaseSubobject {
28  /// Base - The base class declaration.
29  const CXXRecordDecl *Base;
30
31  /// BaseOffset - The offset from the most derived class to the base class.
32  CharUnits BaseOffset;
33
34public:
35  BaseSubobject() { }
36  BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
37    : Base(Base), BaseOffset(BaseOffset) { }
38
39  /// getBase - Returns the base class declaration.
40  const CXXRecordDecl *getBase() const { return Base; }
41
42  /// getBaseOffset - Returns the base class offset.
43  CharUnits getBaseOffset() const { return BaseOffset; }
44
45  friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
46    return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
47 }
48};
49
50} // end namespace clang
51
52namespace llvm {
53
54template<> struct DenseMapInfo<clang::BaseSubobject> {
55  static clang::BaseSubobject getEmptyKey() {
56    return clang::BaseSubobject(
57      DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
58      clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getEmptyKey()));
59  }
60
61  static clang::BaseSubobject getTombstoneKey() {
62    return clang::BaseSubobject(
63      DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
64      clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getTombstoneKey()));
65  }
66
67  static unsigned getHashValue(const clang::BaseSubobject &Base) {
68    typedef std::pair<const clang::CXXRecordDecl *, clang::CharUnits> PairTy;
69    return DenseMapInfo<PairTy>::getHashValue(PairTy(Base.getBase(),
70                                                     Base.getBaseOffset()));
71  }
72
73  static bool isEqual(const clang::BaseSubobject &LHS,
74                      const clang::BaseSubobject &RHS) {
75    return LHS == RHS;
76  }
77};
78
79// It's OK to treat BaseSubobject as a POD type.
80template <> struct isPodLike<clang::BaseSubobject> {
81  static const bool value = true;
82};
83
84}
85
86#endif
87