Home | History | Annotate | Download | only in Index
      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