133446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne//===--- BaseSubobject.h - BaseSubobject class ----------------------------===//
233446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne//
333446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne//                     The LLVM Compiler Infrastructure
433446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne//
533446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne// This file is distributed under the University of Illinois Open Source
633446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne// License. See LICENSE.TXT for details.
733446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne//
833446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne//===----------------------------------------------------------------------===//
933446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne//
1033446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne// This file provides a definition of the BaseSubobject class.
1133446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne//
1233446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne//===----------------------------------------------------------------------===//
1333446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
1433446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne#ifndef LLVM_CLANG_AST_BASESUBOBJECT_H
1533446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne#define LLVM_CLANG_AST_BASESUBOBJECT_H
1633446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
1733446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne#include "clang/AST/CharUnits.h"
1833446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne#include "llvm/ADT/DenseMap.h"
1933446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne#include "llvm/Support/DataTypes.h"
2033446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne#include "llvm/Support/type_traits.h"
2133446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
2233446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbournenamespace clang {
2333446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  class CXXRecordDecl;
2433446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
2533446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne// BaseSubobject - Uniquely identifies a direct or indirect base class.
2633446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne// Stores both the base class decl and the offset from the most derived class to
278f944492f21a2fb61d539d933add5b1fc7b00e94Eli Friedman// the base class. Used for vtable and VTT generation.
2833446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourneclass BaseSubobject {
2933446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  /// Base - The base class declaration.
3033446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  const CXXRecordDecl *Base;
3133446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
3233446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  /// BaseOffset - The offset from the most derived class to the base class.
3333446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  CharUnits BaseOffset;
3433446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
3533446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbournepublic:
3633446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  BaseSubobject() { }
3733446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
3833446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne    : Base(Base), BaseOffset(BaseOffset) { }
3933446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
4033446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  /// getBase - Returns the base class declaration.
4133446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  const CXXRecordDecl *getBase() const { return Base; }
4233446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
4333446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  /// getBaseOffset - Returns the base class offset.
4433446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  CharUnits getBaseOffset() const { return BaseOffset; }
4533446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
4633446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
4733446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne    return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
4833446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne }
4933446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne};
5033446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
5133446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne} // end namespace clang
5233446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
5333446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbournenamespace llvm {
5433446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
5533446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbournetemplate<> struct DenseMapInfo<clang::BaseSubobject> {
5633446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  static clang::BaseSubobject getEmptyKey() {
5733446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne    return clang::BaseSubobject(
5833446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne      DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
5933446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne      clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getEmptyKey()));
6033446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  }
6133446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
6233446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  static clang::BaseSubobject getTombstoneKey() {
6333446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne    return clang::BaseSubobject(
6433446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne      DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
6533446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne      clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getTombstoneKey()));
6633446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  }
6733446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
6833446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  static unsigned getHashValue(const clang::BaseSubobject &Base) {
6928b230723d5daf3c48c2e134f4b5626bd69392c8Benjamin Kramer    typedef std::pair<const clang::CXXRecordDecl *, clang::CharUnits> PairTy;
7028b230723d5daf3c48c2e134f4b5626bd69392c8Benjamin Kramer    return DenseMapInfo<PairTy>::getHashValue(PairTy(Base.getBase(),
7128b230723d5daf3c48c2e134f4b5626bd69392c8Benjamin Kramer                                                     Base.getBaseOffset()));
7233446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  }
7333446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
7433446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  static bool isEqual(const clang::BaseSubobject &LHS,
7533446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne                      const clang::BaseSubobject &RHS) {
7633446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne    return LHS == RHS;
7733446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  }
7833446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne};
7933446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
8033446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne// It's OK to treat BaseSubobject as a POD type.
8133446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbournetemplate <> struct isPodLike<clang::BaseSubobject> {
8233446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne  static const bool value = true;
8333446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne};
8433446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
8533446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne}
8633446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne
8733446f1a22a662335c76e2ef7511e48f61801a35Peter Collingbourne#endif
88