diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2009-07-29 23:41:46 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2009-07-29 23:41:46 +0000 |
commit | 87bcb504f6ea453c50e47beb850258ebe57e9248 (patch) | |
tree | cfaea5acc4e9d8ff21263312068c6f0395f280ed /lib/Index/Entity.cpp | |
parent | e5bb6d49522f5119740a2c87e466725300fee88f (diff) |
Support ObjC methods as Entities.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77547 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Index/Entity.cpp')
-rw-r--r-- | lib/Index/Entity.cpp | 91 |
1 files changed, 65 insertions, 26 deletions
diff --git a/lib/Index/Entity.cpp b/lib/Index/Entity.cpp index 8c7c8d0ef5..245fc9a555 100644 --- a/lib/Index/Entity.cpp +++ b/lib/Index/Entity.cpp @@ -15,6 +15,7 @@ #include "EntityImpl.h" #include "ProgramImpl.h" #include "clang/Index/Program.h" +#include "clang/Index/GlobalSelector.h" #include "clang/AST/Decl.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclVisitor.h" @@ -34,10 +35,12 @@ namespace idx { /// \brief Gets the Entity associated with a Decl. class EntityGetter : public DeclVisitor<EntityGetter, Entity> { - ProgramImpl &Prog; + Program &Prog; + ProgramImpl &ProgImpl; public: - EntityGetter(ProgramImpl &prog) : Prog(prog) { } + EntityGetter(Program &prog, ProgramImpl &progImpl) + : Prog(prog), ProgImpl(progImpl) { } Entity VisitNamedDecl(NamedDecl *D); Entity VisitVarDecl(VarDecl *D); @@ -58,32 +61,49 @@ Entity EntityGetter::VisitNamedDecl(NamedDecl *D) { if (Parent.isValid() && Parent.isInternalToTU()) return Entity(D); - // FIXME: Only works for DeclarationNames that are identifiers. + // FIXME: Only works for DeclarationNames that are identifiers and selectors. // Treats other DeclarationNames as internal Decls for now.. - DeclarationName Name = D->getDeclName(); - - if (!Name.isIdentifier()) + DeclarationName LocalName = D->getDeclName(); + if (!LocalName) return Entity(D); - IdentifierInfo *II = Name.getAsIdentifierInfo(); - if (!II) - return Entity(); + DeclarationName GlobName; + + if (IdentifierInfo *II = LocalName.getAsIdentifierInfo()) { + IdentifierInfo *GlobII = + &ProgImpl.getIdents().get(II->getName(), II->getName() + II->getLength()); + GlobName = DeclarationName(GlobII); + } else { + Selector LocalSel = LocalName.getObjCSelector(); + + // Treats other DeclarationNames as internal Decls for now.. + if (LocalSel.isNull()) + return Entity(D); + + Selector GlobSel = + (uintptr_t)GlobalSelector::get(LocalSel, Prog).getAsOpaquePtr(); + GlobName = DeclarationName(GlobSel); + } + + assert(GlobName); - IdentifierInfo *Id = &Prog.getIdents().get(II->getName(), - II->getName() + II->getLength()); unsigned IdNS = D->getIdentifierNamespace(); + ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D); + bool isObjCInstanceMethod = MD && MD->isInstanceMethod(); + llvm::FoldingSetNodeID ID; - EntityImpl::Profile(ID, Parent, Id, IdNS); + EntityImpl::Profile(ID, Parent, GlobName, IdNS, isObjCInstanceMethod); - ProgramImpl::EntitySetTy &Entities = Prog.getEntities(); + ProgramImpl::EntitySetTy &Entities = ProgImpl.getEntities(); void *InsertPos = 0; if (EntityImpl *Ent = Entities.FindNodeOrInsertPos(ID, InsertPos)) return Entity(Ent); - void *Buf = Prog.Allocate(sizeof(EntityImpl)); - EntityImpl *New = new (Buf) EntityImpl(Parent, Id, IdNS); + void *Buf = ProgImpl.Allocate(sizeof(EntityImpl)); + EntityImpl *New = + new (Buf) EntityImpl(Parent, GlobName, IdNS, isObjCInstanceMethod); Entities.InsertNode(New, InsertPos); return Entity(New); @@ -115,14 +135,33 @@ Decl *EntityImpl::getDecl(ASTContext &AST) { : cast<DeclContext>(Parent.getDecl(AST)); if (!DC) return 0; // Couldn't get the parent context. - - IdentifierInfo &II = AST.Idents.get(Id->getName(), - Id->getName() + Id->getLength()); - - DeclContext::lookup_result Res = DC->lookup(DeclarationName(&II)); + + DeclarationName LocalName; + + if (IdentifierInfo *GlobII = Name.getAsIdentifierInfo()) { + IdentifierInfo &II = AST.Idents.get(GlobII->getName(), + GlobII->getName() + GlobII->getLength()); + LocalName = DeclarationName(&II); + } else { + Selector GlobSel = Name.getObjCSelector(); + assert(!GlobSel.isNull() && "A not handled yet declaration name"); + GlobalSelector GSel = + GlobalSelector::getFromOpaquePtr(GlobSel.getAsOpaquePtr()); + LocalName = GSel.getSelector(AST); + } + + assert(LocalName); + + DeclContext::lookup_result Res = DC->lookup(LocalName); for (DeclContext::lookup_iterator I = Res.first, E = Res.second; I!=E; ++I) { - if ((*I)->getIdentifierNamespace() == IdNS) - return *I; + Decl *D = *I; + if (D->getIdentifierNamespace() == IdNS) { + if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { + if (MD->isInstanceMethod() == IsObjCInstanceMethod) + return MD; + } else + return D; + } } return 0; // Failed to find a decl using this Entity. @@ -130,13 +169,13 @@ Decl *EntityImpl::getDecl(ASTContext &AST) { /// \brief Get an Entity associated with the given Decl. /// \returns Null if an Entity cannot refer to this Decl. -Entity EntityImpl::get(Decl *D, ProgramImpl &Prog) { +Entity EntityImpl::get(Decl *D, Program &Prog, ProgramImpl &ProgImpl) { assert(D && "Passed null Decl"); - return EntityGetter(Prog).Visit(D); + return EntityGetter(Prog, ProgImpl).Visit(D); } std::string EntityImpl::getPrintableName() { - return Id->getName(); + return Name.getAsString(); } //===----------------------------------------------------------------------===// @@ -177,7 +216,7 @@ Entity Entity::get(Decl *D, Program &Prog) { if (D == 0) return Entity(); ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl); - return EntityImpl::get(D, ProgImpl); + return EntityImpl::get(D, Prog, ProgImpl); } unsigned |