DeclAccessPair.h revision 161755a09898c95d21bfff33707da9ca41cd53c5
1161755a09898c95d21bfff33707da9ca41cd53c5John McCall//===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===//
2161755a09898c95d21bfff33707da9ca41cd53c5John McCall//
3161755a09898c95d21bfff33707da9ca41cd53c5John McCall//                     The LLVM Compiler Infrastructure
4161755a09898c95d21bfff33707da9ca41cd53c5John McCall//
5161755a09898c95d21bfff33707da9ca41cd53c5John McCall// This file is distributed under the University of Illinois Open Source
6161755a09898c95d21bfff33707da9ca41cd53c5John McCall// License. See LICENSE.TXT for details.
7161755a09898c95d21bfff33707da9ca41cd53c5John McCall//
8161755a09898c95d21bfff33707da9ca41cd53c5John McCall//===----------------------------------------------------------------------===//
9161755a09898c95d21bfff33707da9ca41cd53c5John McCall//
10161755a09898c95d21bfff33707da9ca41cd53c5John McCall//  This file defines the DeclAccessPair class, which provides an
11161755a09898c95d21bfff33707da9ca41cd53c5John McCall//  efficient representation of a pair of a NamedDecl* and an
12161755a09898c95d21bfff33707da9ca41cd53c5John McCall//  AccessSpecifier.  Generally the access specifier gives the
13161755a09898c95d21bfff33707da9ca41cd53c5John McCall//  natural access of a declaration when named in a class, as
14161755a09898c95d21bfff33707da9ca41cd53c5John McCall//  defined in C++ [class.access.base]p1.
15161755a09898c95d21bfff33707da9ca41cd53c5John McCall//
16161755a09898c95d21bfff33707da9ca41cd53c5John McCall//===----------------------------------------------------------------------===//
17161755a09898c95d21bfff33707da9ca41cd53c5John McCall
18161755a09898c95d21bfff33707da9ca41cd53c5John McCall#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
19161755a09898c95d21bfff33707da9ca41cd53c5John McCall#define LLVM_CLANG_AST_DECLACCESSPAIR_H
20161755a09898c95d21bfff33707da9ca41cd53c5John McCall
21161755a09898c95d21bfff33707da9ca41cd53c5John McCall#include "clang/Basic/Specifiers.h"
22161755a09898c95d21bfff33707da9ca41cd53c5John McCall
23161755a09898c95d21bfff33707da9ca41cd53c5John McCallnamespace clang {
24161755a09898c95d21bfff33707da9ca41cd53c5John McCall
25161755a09898c95d21bfff33707da9ca41cd53c5John McCallclass NamedDecl;
26161755a09898c95d21bfff33707da9ca41cd53c5John McCall
27161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// A POD class for pairing a NamedDecl* with an access specifier.
28161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// Can be put into unions.
29161755a09898c95d21bfff33707da9ca41cd53c5John McCallclass DeclAccessPair {
30161755a09898c95d21bfff33707da9ca41cd53c5John McCall  NamedDecl *Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
31161755a09898c95d21bfff33707da9ca41cd53c5John McCall
32161755a09898c95d21bfff33707da9ca41cd53c5John McCall  enum { Mask = 0x3 };
33161755a09898c95d21bfff33707da9ca41cd53c5John McCall
34161755a09898c95d21bfff33707da9ca41cd53c5John McCallpublic:
35161755a09898c95d21bfff33707da9ca41cd53c5John McCall  static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
36161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DeclAccessPair p;
37161755a09898c95d21bfff33707da9ca41cd53c5John McCall    p.set(D, AS);
38161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return p;
39161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
40161755a09898c95d21bfff33707da9ca41cd53c5John McCall
41161755a09898c95d21bfff33707da9ca41cd53c5John McCall  NamedDecl *getDecl() const {
42161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return (NamedDecl*) (~Mask & (uintptr_t) Ptr);
43161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
44161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessSpecifier getAccess() const {
45161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AccessSpecifier(Mask & (uintptr_t) Ptr);
46161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
47161755a09898c95d21bfff33707da9ca41cd53c5John McCall
48161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void setDecl(NamedDecl *D) {
49161755a09898c95d21bfff33707da9ca41cd53c5John McCall    set(D, getAccess());
50161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
51161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void setAccess(AccessSpecifier AS) {
52161755a09898c95d21bfff33707da9ca41cd53c5John McCall    set(getDecl(), AS);
53161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
54161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void set(NamedDecl *D, AccessSpecifier AS) {
55161755a09898c95d21bfff33707da9ca41cd53c5John McCall    Ptr = reinterpret_cast<NamedDecl*>(uintptr_t(AS) |
56161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                       reinterpret_cast<uintptr_t>(D));
57161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
58161755a09898c95d21bfff33707da9ca41cd53c5John McCall
59161755a09898c95d21bfff33707da9ca41cd53c5John McCall  operator NamedDecl*() const { return getDecl(); }
60161755a09898c95d21bfff33707da9ca41cd53c5John McCall  NamedDecl *operator->() const { return getDecl(); }
61161755a09898c95d21bfff33707da9ca41cd53c5John McCall};
62161755a09898c95d21bfff33707da9ca41cd53c5John McCall}
63161755a09898c95d21bfff33707da9ca41cd53c5John McCall
64161755a09898c95d21bfff33707da9ca41cd53c5John McCall// Take a moment to tell SmallVector that DeclAccessPair is POD.
65161755a09898c95d21bfff33707da9ca41cd53c5John McCallnamespace llvm {
66161755a09898c95d21bfff33707da9ca41cd53c5John McCalltemplate<typename> struct isPodLike;
67161755a09898c95d21bfff33707da9ca41cd53c5John McCalltemplate<> struct isPodLike<clang::DeclAccessPair> {
68161755a09898c95d21bfff33707da9ca41cd53c5John McCall   static const bool value = true;
69161755a09898c95d21bfff33707da9ca41cd53c5John McCall};
70161755a09898c95d21bfff33707da9ca41cd53c5John McCall}
71161755a09898c95d21bfff33707da9ca41cd53c5John McCall
72161755a09898c95d21bfff33707da9ca41cd53c5John McCall#endif
73