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 "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