clang API Documentation
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 }