clang API Documentation

Entity.cpp
Go to the documentation of this file.
00001 //===--- Entity.cpp - Cross-translation-unit "token" for decls ------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  Entity is a ASTContext-independent way to refer to declarations that are
00011 //  visible across translation units.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "EntityImpl.h"
00016 #include "ProgramImpl.h"
00017 #include "clang/Index/Program.h"
00018 #include "clang/Index/GlobalSelector.h"
00019 #include "clang/AST/Decl.h"
00020 #include "clang/AST/ASTContext.h"
00021 #include "clang/AST/DeclVisitor.h"
00022 using namespace clang;
00023 using namespace idx;
00024 
00025 // FIXME: Entity is really really basic currently, mostly written to work
00026 // on variables and functions. Should support types and other decls eventually..
00027 
00028 
00029 //===----------------------------------------------------------------------===//
00030 // EntityGetter
00031 //===----------------------------------------------------------------------===//
00032 
00033 namespace clang {
00034 namespace idx {
00035 
00036 /// \brief Gets the Entity associated with a Decl.
00037 class EntityGetter : public DeclVisitor<EntityGetter, Entity> {
00038   Program &Prog;
00039   ProgramImpl &ProgImpl;
00040 
00041 public:
00042   EntityGetter(Program &prog, ProgramImpl &progImpl)
00043     : Prog(prog), ProgImpl(progImpl) { }
00044 
00045   // Get an Entity.
00046   Entity getEntity(Entity Parent, DeclarationName Name, 
00047                    unsigned IdNS, bool isObjCInstanceMethod);
00048 
00049   // Get an Entity associated with the name in the global namespace.
00050   Entity getGlobalEntity(StringRef Name);
00051 
00052   Entity VisitNamedDecl(NamedDecl *D);
00053   Entity VisitVarDecl(VarDecl *D);
00054   Entity VisitFieldDecl(FieldDecl *D);
00055   Entity VisitFunctionDecl(FunctionDecl *D);
00056   Entity VisitTypeDecl(TypeDecl *D);
00057 };
00058 
00059 }
00060 }
00061 
00062 Entity EntityGetter::getEntity(Entity Parent, DeclarationName Name, 
00063                                unsigned IdNS, bool isObjCInstanceMethod) {
00064   llvm::FoldingSetNodeID ID;
00065   EntityImpl::Profile(ID, Parent, Name, IdNS, isObjCInstanceMethod);
00066 
00067   ProgramImpl::EntitySetTy &Entities = ProgImpl.getEntities();
00068   void *InsertPos = 0;
00069   if (EntityImpl *Ent = Entities.FindNodeOrInsertPos(ID, InsertPos))
00070     return Entity(Ent);
00071 
00072   void *Buf = ProgImpl.Allocate(sizeof(EntityImpl));
00073   EntityImpl *New =
00074       new (Buf) EntityImpl(Parent, Name, IdNS, isObjCInstanceMethod);
00075   Entities.InsertNode(New, InsertPos);
00076 
00077   return Entity(New);
00078 }
00079 
00080 Entity EntityGetter::getGlobalEntity(StringRef Name) {
00081   IdentifierInfo *II = &ProgImpl.getIdents().get(Name);
00082   DeclarationName GlobName(II);
00083   unsigned IdNS = Decl::IDNS_Ordinary;
00084   return getEntity(Entity(), GlobName, IdNS, false);
00085 }
00086 
00087 Entity EntityGetter::VisitNamedDecl(NamedDecl *D) {
00088   Entity Parent;
00089   if (!D->getDeclContext()->isTranslationUnit()) {
00090     Parent = Visit(cast<Decl>(D->getDeclContext()));
00091     // FIXME: Anonymous structs ?
00092     if (Parent.isInvalid())
00093       return Entity();
00094   }
00095   if (Parent.isValid() && Parent.isInternalToTU())
00096     return Entity(D);
00097 
00098   // FIXME: Only works for DeclarationNames that are identifiers and selectors.
00099   // Treats other DeclarationNames as internal Decls for now..
00100 
00101   DeclarationName LocalName = D->getDeclName();
00102   if (!LocalName)
00103     return Entity(D);
00104 
00105   DeclarationName GlobName;
00106 
00107   if (IdentifierInfo *II = LocalName.getAsIdentifierInfo()) {
00108     IdentifierInfo *GlobII = &ProgImpl.getIdents().get(II->getName());
00109     GlobName = DeclarationName(GlobII);
00110   } else {
00111     Selector LocalSel = LocalName.getObjCSelector();
00112 
00113     // Treats other DeclarationNames as internal Decls for now..
00114     if (LocalSel.isNull())
00115       return Entity(D);
00116 
00117     Selector GlobSel =
00118         (uintptr_t)GlobalSelector::get(LocalSel, Prog).getAsOpaquePtr();
00119     GlobName = DeclarationName(GlobSel);
00120   }
00121 
00122   assert(GlobName);
00123 
00124   unsigned IdNS = D->getIdentifierNamespace();
00125 
00126   ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D);
00127   bool isObjCInstanceMethod = MD && MD->isInstanceMethod();
00128   return getEntity(Parent, GlobName, IdNS, isObjCInstanceMethod);
00129 }
00130 
00131 Entity EntityGetter::VisitVarDecl(VarDecl *D) {
00132   // Local variables have no linkage, make invalid Entities.
00133   if (D->hasLocalStorage())
00134     return Entity();
00135 
00136   // If it's static it cannot be referred to by another translation unit.
00137   if (D->getStorageClass() == SC_Static)
00138     return Entity(D);
00139 
00140   return VisitNamedDecl(D);
00141 }
00142 
00143 Entity EntityGetter::VisitFunctionDecl(FunctionDecl *D) {
00144   // If it's static it cannot be referred to by another translation unit.
00145   if (D->getStorageClass() == SC_Static)
00146     return Entity(D);
00147 
00148   return VisitNamedDecl(D);
00149 }
00150 
00151 Entity EntityGetter::VisitFieldDecl(FieldDecl *D) {
00152   // Make FieldDecl an invalid Entity since it has no linkage.
00153   return Entity();
00154 }
00155 
00156 Entity EntityGetter::VisitTypeDecl(TypeDecl *D) {
00157   // Although in C++ class name has external linkage, usually the definition of
00158   // the class is available in the same translation unit when it's needed. So we
00159   // make all of them invalid Entity.
00160   return Entity();
00161 }
00162 
00163 //===----------------------------------------------------------------------===//
00164 // EntityImpl Implementation
00165 //===----------------------------------------------------------------------===//
00166 
00167 Decl *EntityImpl::getDecl(ASTContext &AST) {
00168   DeclContext *DC =
00169     Parent.isInvalid() ? AST.getTranslationUnitDecl()
00170                        : cast<DeclContext>(Parent.getDecl(AST));
00171   if (!DC)
00172     return 0; // Couldn't get the parent context.
00173 
00174   DeclarationName LocalName;
00175 
00176   if (IdentifierInfo *GlobII = Name.getAsIdentifierInfo()) {
00177     IdentifierInfo &II = AST.Idents.get(GlobII->getName());
00178     LocalName = DeclarationName(&II);
00179   } else {
00180     Selector GlobSel = Name.getObjCSelector();
00181     assert(!GlobSel.isNull() && "A not handled yet declaration name");
00182     GlobalSelector GSel =
00183         GlobalSelector::getFromOpaquePtr(GlobSel.getAsOpaquePtr());
00184     LocalName = GSel.getSelector(AST);
00185   }
00186 
00187   assert(LocalName);
00188 
00189   DeclContext::lookup_result Res = DC->lookup(LocalName);
00190   for (DeclContext::lookup_iterator I = Res.first, E = Res.second; I!=E; ++I) {
00191     Decl *D = *I;
00192     if (D->getIdentifierNamespace() == IdNS) {
00193       if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
00194         if (MD->isInstanceMethod() == IsObjCInstanceMethod)
00195           return MD;
00196       } else
00197         return D;
00198     }
00199   }
00200 
00201   return 0; // Failed to find a decl using this Entity.
00202 }
00203 
00204 /// \brief Get an Entity associated with the given Decl.
00205 /// \returns Null if an Entity cannot refer to this Decl.
00206 Entity EntityImpl::get(Decl *D, Program &Prog, ProgramImpl &ProgImpl) {
00207   assert(D && "Passed null Decl");
00208   return EntityGetter(Prog, ProgImpl).Visit(D);
00209 }
00210 
00211 /// \brief Get an Entity associated with a global name.
00212 Entity EntityImpl::get(StringRef Name, Program &Prog, 
00213                        ProgramImpl &ProgImpl) {
00214   return EntityGetter(Prog, ProgImpl).getGlobalEntity(Name);
00215 }
00216 
00217 std::string EntityImpl::getPrintableName() {
00218   return Name.getAsString();
00219 }
00220 
00221 //===----------------------------------------------------------------------===//
00222 // Entity Implementation
00223 //===----------------------------------------------------------------------===//
00224 
00225 Entity::Entity(Decl *D) : Val(D->getCanonicalDecl()) { }
00226 
00227 /// \brief Find the Decl that can be referred to by this entity.
00228 Decl *Entity::getDecl(ASTContext &AST) const {
00229   if (isInvalid())
00230     return 0;
00231 
00232   if (Decl *D = Val.dyn_cast<Decl *>())
00233     // Check that the passed AST is actually the one that this Decl belongs to.
00234     return (&D->getASTContext() == &AST) ? D : 0;
00235 
00236   return Val.get<EntityImpl *>()->getDecl(AST);
00237 }
00238 
00239 std::string Entity::getPrintableName() const {
00240   if (isInvalid())
00241     return "<< Invalid >>";
00242 
00243   if (Decl *D = Val.dyn_cast<Decl *>()) {
00244     if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
00245       return ND->getNameAsString();
00246     else
00247       return std::string();
00248   }
00249 
00250   return Val.get<EntityImpl *>()->getPrintableName();
00251 }
00252 
00253 /// \brief Get an Entity associated with the given Decl.
00254 /// \returns Null if an Entity cannot refer to this Decl.
00255 Entity Entity::get(Decl *D, Program &Prog) {
00256   if (D == 0)
00257     return Entity();
00258   ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl);
00259   return EntityImpl::get(D, Prog, ProgImpl);
00260 }
00261 
00262 Entity Entity::get(StringRef Name, Program &Prog) {
00263   ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl);
00264   return EntityImpl::get(Name, Prog, ProgImpl);
00265 }
00266 
00267 unsigned
00268 llvm::DenseMapInfo<Entity>::getHashValue(Entity E) {
00269   return DenseMapInfo<void*>::getHashValue(E.getAsOpaquePtr());
00270 }