aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Index/Entity.h
blob: 9863963ff217254dea25f9541ced8558b2b416de (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//===--- Entity.h - Cross-translation-unit "token" for decls ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  Entity is a ASTContext-independent way to refer to declarations that are
//  visible across translation units.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_INDEX_ENTITY_H
#define LLVM_CLANG_INDEX_ENTITY_H

#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include <string>

namespace clang {
  class ASTContext;
  class Decl;

namespace idx {
  class Program;
  class EntityImpl;

/// \brief A ASTContext-independent way to refer to declarations.
///
/// Entity is basically the link for declarations that are semantically the same
/// in multiple ASTContexts. A client will convert a Decl into an Entity and
/// later use that Entity to find the "same" Decl into another ASTContext.
/// Declarations that are semantically the same and visible across translation
/// units will be associated with the same Entity.
///
/// An Entity may also refer to declarations that cannot be visible across
/// translation units, e.g. static functions with the same name in multiple
/// translation units will be associated with different Entities.
///
/// Entities can be checked for equality but note that the same Program object
/// should be used when getting Entities.
///
class Entity {
  /// \brief Stores the Decl directly if it is not visible outside of its own
  /// translation unit, otherwise it stores the associated EntityImpl.
  llvm::PointerUnion<Decl *, EntityImpl *> Val;

  explicit Entity(Decl *D);
  explicit Entity(EntityImpl *impl) : Val(impl) { }
  friend class EntityGetter;

public:
  Entity() { }

  /// \brief Find the Decl that can be referred to by this entity.
  Decl *getDecl(ASTContext &AST) const;

  /// \brief If this Entity represents a declaration that is internal to its
  /// translation unit, getInternalDecl() returns it.
  Decl *getInternalDecl() const {
    assert(isInternalToTU() && "This Entity is not internal!");
    return Val.get<Decl *>();
  }

  /// \brief Get a printable name for debugging purpose.
  std::string getPrintableName() const;

  /// \brief Get an Entity associated with the given Decl.
  /// \returns invalid Entity if an Entity cannot refer to this Decl.
  static Entity get(Decl *D, Program &Prog);

  /// \brief Get an Entity associated with a name in the global namespace.
  static Entity get(llvm::StringRef Name, Program &Prog);

  /// \brief true if the Entity is not visible outside the trasnlation unit.
  bool isInternalToTU() const {
    assert(isValid() && "This Entity is not valid!");
    return Val.is<Decl *>();
  }

  bool isValid() const { return !Val.isNull(); }
  bool isInvalid() const { return !isValid(); }

  void *getAsOpaquePtr() const { return Val.getOpaqueValue(); }
  static Entity getFromOpaquePtr(void *Ptr) {
    Entity Ent;
    Ent.Val = llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue(Ptr);
    return Ent;
  }

  friend bool operator==(const Entity &LHS, const Entity &RHS) {
    return LHS.getAsOpaquePtr() == RHS.getAsOpaquePtr();
  }

  // For use in a std::map.
  friend bool operator < (const Entity &LHS, const Entity &RHS) {
    return LHS.getAsOpaquePtr() < RHS.getAsOpaquePtr();
  }

  // For use in DenseMap/DenseSet.
  static Entity getEmptyMarker() {
    Entity Ent;
    Ent.Val =
      llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue((void*)-1);
    return Ent;
  }
  static Entity getTombstoneMarker() {
    Entity Ent;
    Ent.Val =
      llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue((void*)-2);
    return Ent;
  }
};

} // namespace idx

} // namespace clang

namespace llvm {
/// Define DenseMapInfo so that Entities can be used as keys in DenseMap and
/// DenseSets.
template<>
struct DenseMapInfo<clang::idx::Entity> {
  static inline clang::idx::Entity getEmptyKey() {
    return clang::idx::Entity::getEmptyMarker();
  }

  static inline clang::idx::Entity getTombstoneKey() {
    return clang::idx::Entity::getTombstoneMarker();
  }

  static unsigned getHashValue(clang::idx::Entity);

  static inline bool
  isEqual(clang::idx::Entity LHS, clang::idx::Entity RHS) {
    return LHS == RHS;
  }
};
  
template <>
struct isPodLike<clang::idx::Entity> { static const bool value = true; };

}  // end namespace llvm

#endif