1 //===--- Entity.h - Cross-translation-unit "token" for decls ----*- C++ -*-===// 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 // Entity is a ASTContext-independent way to refer to declarations that are 11 // visible across translation units. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_INDEX_ENTITY_H 16 #define LLVM_CLANG_INDEX_ENTITY_H 17 18 #include "clang/Basic/LLVM.h" 19 #include "llvm/ADT/PointerUnion.h" 20 #include "llvm/ADT/DenseMap.h" 21 #include "llvm/ADT/StringRef.h" 22 #include <string> 23 24 namespace clang { 25 class ASTContext; 26 class Decl; 27 28 namespace idx { 29 class Program; 30 class EntityImpl; 31 32 /// \brief A ASTContext-independent way to refer to declarations. 33 /// 34 /// Entity is basically the link for declarations that are semantically the same 35 /// in multiple ASTContexts. A client will convert a Decl into an Entity and 36 /// later use that Entity to find the "same" Decl into another ASTContext. 37 /// Declarations that are semantically the same and visible across translation 38 /// units will be associated with the same Entity. 39 /// 40 /// An Entity may also refer to declarations that cannot be visible across 41 /// translation units, e.g. static functions with the same name in multiple 42 /// translation units will be associated with different Entities. 43 /// 44 /// Entities can be checked for equality but note that the same Program object 45 /// should be used when getting Entities. 46 /// 47 class Entity { 48 /// \brief Stores the Decl directly if it is not visible outside of its own 49 /// translation unit, otherwise it stores the associated EntityImpl. 50 llvm::PointerUnion<Decl *, EntityImpl *> Val; 51 52 explicit Entity(Decl *D); 53 explicit Entity(EntityImpl *impl) : Val(impl) { } 54 friend class EntityGetter; 55 56 public: 57 Entity() { } 58 59 /// \brief Find the Decl that can be referred to by this entity. 60 Decl *getDecl(ASTContext &AST) const; 61 62 /// \brief If this Entity represents a declaration that is internal to its 63 /// translation unit, getInternalDecl() returns it. 64 Decl *getInternalDecl() const { 65 assert(isInternalToTU() && "This Entity is not internal!"); 66 return Val.get<Decl *>(); 67 } 68 69 /// \brief Get a printable name for debugging purpose. 70 std::string getPrintableName() const; 71 72 /// \brief Get an Entity associated with the given Decl. 73 /// \returns invalid Entity if an Entity cannot refer to this Decl. 74 static Entity get(Decl *D, Program &Prog); 75 76 /// \brief Get an Entity associated with a name in the global namespace. 77 static Entity get(StringRef Name, Program &Prog); 78 79 /// \brief true if the Entity is not visible outside the trasnlation unit. 80 bool isInternalToTU() const { 81 assert(isValid() && "This Entity is not valid!"); 82 return Val.is<Decl *>(); 83 } 84 85 bool isValid() const { return !Val.isNull(); } 86 bool isInvalid() const { return !isValid(); } 87 88 void *getAsOpaquePtr() const { return Val.getOpaqueValue(); } 89 static Entity getFromOpaquePtr(void *Ptr) { 90 Entity Ent; 91 Ent.Val = llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue(Ptr); 92 return Ent; 93 } 94 95 friend bool operator==(const Entity &LHS, const Entity &RHS) { 96 return LHS.getAsOpaquePtr() == RHS.getAsOpaquePtr(); 97 } 98 99 // For use in a std::map. 100 friend bool operator < (const Entity &LHS, const Entity &RHS) { 101 return LHS.getAsOpaquePtr() < RHS.getAsOpaquePtr(); 102 } 103 104 // For use in DenseMap/DenseSet. 105 static Entity getEmptyMarker() { 106 Entity Ent; 107 Ent.Val = 108 llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue((void*)-1); 109 return Ent; 110 } 111 static Entity getTombstoneMarker() { 112 Entity Ent; 113 Ent.Val = 114 llvm::PointerUnion<Decl *, EntityImpl *>::getFromOpaqueValue((void*)-2); 115 return Ent; 116 } 117 }; 118 119 } // namespace idx 120 121 } // namespace clang 122 123 namespace llvm { 124 /// Define DenseMapInfo so that Entities can be used as keys in DenseMap and 125 /// DenseSets. 126 template<> 127 struct DenseMapInfo<clang::idx::Entity> { 128 static inline clang::idx::Entity getEmptyKey() { 129 return clang::idx::Entity::getEmptyMarker(); 130 } 131 132 static inline clang::idx::Entity getTombstoneKey() { 133 return clang::idx::Entity::getTombstoneMarker(); 134 } 135 136 static unsigned getHashValue(clang::idx::Entity); 137 138 static inline bool 139 isEqual(clang::idx::Entity LHS, clang::idx::Entity RHS) { 140 return LHS == RHS; 141 } 142 }; 143 144 template <> 145 struct isPodLike<clang::idx::Entity> { static const bool value = true; }; 146 147 } // end namespace llvm 148 149 #endif 150