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 | 2eff90515f7b94be9883f2ac361520866ee869df (patch) | |
| tree | f09ab629d56dcc0dbb8a19e61a1c24a978d1807c /clang/lib | |
| parent | 82c80a59ee7c0f8a474cf9e4d195eef2417d127b (diff) | |
| download | bcm5719-llvm-2eff90515f7b94be9883f2ac361520866ee869df.tar.gz bcm5719-llvm-2eff90515f7b94be9883f2ac361520866ee869df.zip  | |
Support ObjC methods as Entities.
llvm-svn: 77547
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Index/Entity.cpp | 91 | ||||
| -rw-r--r-- | clang/lib/Index/EntityImpl.h | 24 | 
2 files changed, 81 insertions, 34 deletions
diff --git a/clang/lib/Index/Entity.cpp b/clang/lib/Index/Entity.cpp index 8c7c8d0ef57..245fc9a5551 100644 --- a/clang/lib/Index/Entity.cpp +++ b/clang/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  diff --git a/clang/lib/Index/EntityImpl.h b/clang/lib/Index/EntityImpl.h index d28936ee2cb..b4a883a3bf8 100644 --- a/clang/lib/Index/EntityImpl.h +++ b/clang/lib/Index/EntityImpl.h @@ -15,43 +15,51 @@  #define LLVM_CLANG_INDEX_ENTITYIMPL_H  #include "clang/Index/Entity.h" +#include "clang/AST/DeclarationName.h"  #include "llvm/ADT/FoldingSet.h"  #include "llvm/ADT/StringSet.h"  namespace clang { -  class IdentifierInfo;  namespace idx {    class ProgramImpl;  class EntityImpl : public llvm::FoldingSetNode {    Entity Parent; -  IdentifierInfo *Id; +  DeclarationName Name;    /// \brief Identifier namespace.    unsigned IdNS; +   +  /// \brief If Name is a selector, this keeps track whether it's for an +  /// instance method. +  bool IsObjCInstanceMethod;  public: -  EntityImpl(Entity parent, IdentifierInfo *id, unsigned idNS) -    : Parent(parent), Id(id), IdNS(idNS) { } +  EntityImpl(Entity parent, DeclarationName name, unsigned idNS, +             bool isObjCInstanceMethod) +    : Parent(parent), Name(name), IdNS(idNS), +      IsObjCInstanceMethod(isObjCInstanceMethod) { }    /// \brief Find the Decl that can be referred to by this entity.    Decl *getDecl(ASTContext &AST);    /// \brief Get an Entity associated with the given Decl.    /// \returns Null if an Entity cannot refer to this Decl. -  static Entity get(Decl *D, ProgramImpl &Prog); +  static Entity get(Decl *D, Program &Prog, ProgramImpl &ProgImpl);    std::string getPrintableName();    void Profile(llvm::FoldingSetNodeID &ID) const { -    Profile(ID, Parent, Id, IdNS); +    Profile(ID, Parent, Name, IdNS, IsObjCInstanceMethod);    }    static void Profile(llvm::FoldingSetNodeID &ID, Entity Parent, -                      IdentifierInfo *Id, unsigned IdNS) { +                      DeclarationName Name, unsigned IdNS, +                      bool isObjCInstanceMethod) {      ID.AddPointer(Parent.getAsOpaquePtr()); -    ID.AddPointer(Id); +    ID.AddPointer(Name.getAsOpaquePtr());      ID.AddInteger(IdNS); +    ID.AddBoolean(isObjCInstanceMethod);    }  };  | 

