diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2009-07-21 00:07:06 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2009-07-21 00:07:06 +0000 |
commit | f7cf15ca3c9bee7c0348f549e7a8f0af32b5fa54 (patch) | |
tree | 05e1fd135984a32777ddfbd291bfdc913046d50a /include/clang/Index/Entity.h | |
parent | 07ef804f918d8aade8739a02e78c6209fd3062a9 (diff) |
Change the semantics for Entity.
Entity can now refer to declarations that are not visible outside the translation unit.
It is a wrapper of a pointer union, it's either a Decl* for declarations that don't
"cross" translation units, or an EntityImpl* which is associated with the specific "visible" Decl.
Included is a test case for handling fields across translation units.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76515 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Index/Entity.h')
-rw-r--r-- | include/clang/Index/Entity.h | 105 |
1 files changed, 84 insertions, 21 deletions
diff --git a/include/clang/Index/Entity.h b/include/clang/Index/Entity.h index e1671bbdce..9a5b126d11 100644 --- a/include/clang/Index/Entity.h +++ b/include/clang/Index/Entity.h @@ -15,7 +15,9 @@ #ifndef LLVM_CLANG_INDEX_ENTITY_H #define LLVM_CLANG_INDEX_ENTITY_H -#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/DenseMap.h" +#include <string> namespace clang { class ASTContext; @@ -23,23 +25,35 @@ namespace clang { namespace idx { class Program; + class EntityImpl; -/// \brief A ASTContext-independent way to refer to declarations that are -/// visible across translation units. +/// \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 only refer to declarations that can be visible by multiple -/// translation units, e.g. a static function cannot have an Entity associated -/// with it. +/// 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 are uniqued so pointer equality can be used (note that the same -/// Program object should be used when getting Entities). +/// Entities can be checked for equality but note that the same Program object +/// should be used when getting Entities. /// -class Entity : public llvm::FoldingSetNode { +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) : Val(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); @@ -48,26 +62,75 @@ public: /// \brief Get an Entity associated with the given Decl. /// \returns Null if an Entity cannot refer to this Decl. - static Entity *get(Decl *D, Program &Prog); + static Entity get(Decl *D, Program &Prog); - void Profile(llvm::FoldingSetNodeID &ID) const { - Profile(ID, Parent, Id); - } - static void Profile(llvm::FoldingSetNodeID &ID, Entity *Parent, void *Id) { - ID.AddPointer(Parent); - ID.AddPointer(Id); + /// \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(); } -private: - Entity *Parent; - void *Id; + 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(); + } - Entity(Entity *parent, void *id) : Parent(parent), Id(id) { } - friend class EntityGetter; + // 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; + } + + static inline bool isPod() { return true; } +}; + +} // end namespace llvm + #endif |