Support ObjC methods as Entities.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77547 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Index/Entity.cpp b/lib/Index/Entity.cpp
index 8c7c8d0..245fc9a 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 @@
/// \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 @@
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;
- IdentifierInfo *Id = &Prog.getIdents().get(II->getName(),
- II->getName() + II->getLength());
+ 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);
+
unsigned IdNS = D->getIdentifierNamespace();
- llvm::FoldingSetNodeID ID;
- EntityImpl::Profile(ID, Parent, Id, IdNS);
+ ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D);
+ bool isObjCInstanceMethod = MD && MD->isInstanceMethod();
- ProgramImpl::EntitySetTy &Entities = Prog.getEntities();
+ llvm::FoldingSetNodeID ID;
+ EntityImpl::Profile(ID, Parent, GlobName, IdNS, isObjCInstanceMethod);
+
+ 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 @@
: 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 @@
/// \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 @@
if (D == 0)
return Entity();
ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl);
- return EntityImpl::get(D, ProgImpl);
+ return EntityImpl::get(D, Prog, ProgImpl);
}
unsigned