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