diff options
Diffstat (limited to 'lib/Index/Analyzer.cpp')
| -rw-r--r-- | lib/Index/Analyzer.cpp | 470 | 
1 files changed, 0 insertions, 470 deletions
diff --git a/lib/Index/Analyzer.cpp b/lib/Index/Analyzer.cpp deleted file mode 100644 index f77e6ef92d685..0000000000000 --- a/lib/Index/Analyzer.cpp +++ /dev/null @@ -1,470 +0,0 @@ -//===--- Analyzer.cpp - Analysis for indexing information -------*- C++ -*-===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Analyzer interface. -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/Analyzer.h" -#include "clang/Index/Entity.h" -#include "clang/Index/TranslationUnit.h" -#include "clang/Index/Handlers.h" -#include "clang/Index/ASTLocation.h" -#include "clang/Index/GlobalSelector.h" -#include "clang/Index/DeclReferenceMap.h" -#include "clang/Index/SelectorMap.h" -#include "clang/Index/IndexProvider.h" -#include "clang/AST/DeclObjC.h" -#include "clang/AST/ExprObjC.h" -#include "llvm/ADT/SmallSet.h" -using namespace clang; -using namespace idx; - -namespace  { - -//===----------------------------------------------------------------------===// -// DeclEntityAnalyzer Implementation -//===----------------------------------------------------------------------===// - -class DeclEntityAnalyzer : public TranslationUnitHandler { -  Entity Ent; -  TULocationHandler &TULocHandler; - -public: -  DeclEntityAnalyzer(Entity ent, TULocationHandler &handler) -    : Ent(ent), TULocHandler(handler) { } - -  virtual void Handle(TranslationUnit *TU) { -    assert(TU && "Passed null translation unit"); - -    Decl *D = Ent.getDecl(TU->getASTContext()); -    assert(D && "Couldn't resolve Entity"); - -    for (Decl::redecl_iterator I = D->redecls_begin(), -                               E = D->redecls_end(); I != E; ++I) -      TULocHandler.Handle(TULocation(TU, ASTLocation(*I))); -  } -}; - -//===----------------------------------------------------------------------===// -// RefEntityAnalyzer Implementation -//===----------------------------------------------------------------------===// - -class RefEntityAnalyzer : public TranslationUnitHandler { -  Entity Ent; -  TULocationHandler &TULocHandler; - -public: -  RefEntityAnalyzer(Entity ent, TULocationHandler &handler) -    : Ent(ent), TULocHandler(handler) { } - -  virtual void Handle(TranslationUnit *TU) { -    assert(TU && "Passed null translation unit"); - -    Decl *D = Ent.getDecl(TU->getASTContext()); -    assert(D && "Couldn't resolve Entity"); -    NamedDecl *ND = dyn_cast<NamedDecl>(D); -    if (!ND) -      return; - -    DeclReferenceMap &RefMap = TU->getDeclReferenceMap(); -    for (DeclReferenceMap::astlocation_iterator -           I = RefMap.refs_begin(ND), E = RefMap.refs_end(ND); I != E; ++I) -      TULocHandler.Handle(TULocation(TU, *I)); -  } -}; - -//===----------------------------------------------------------------------===// -// RefSelectorAnalyzer Implementation -//===----------------------------------------------------------------------===// - -/// \brief Accepts an ObjC method and finds all message expressions that this -/// method may respond to. -class RefSelectorAnalyzer : public TranslationUnitHandler { -  Program &Prog; -  TULocationHandler &TULocHandler; - -  // The original ObjCInterface associated with the method. -  Entity IFaceEnt; -  GlobalSelector GlobSel; -  bool IsInstanceMethod; - -  /// \brief Super classes of the ObjCInterface. -  typedef llvm::SmallSet<Entity, 16> EntitiesSetTy; -  EntitiesSetTy HierarchyEntities; - -public: -  RefSelectorAnalyzer(ObjCMethodDecl *MD, -                      Program &prog, TULocationHandler &handler) -    : Prog(prog), TULocHandler(handler) { -    assert(MD); - -    // FIXME: Protocol methods. -    assert(!isa<ObjCProtocolDecl>(MD->getDeclContext()) && -           "Protocol methods not supported yet"); - -    ObjCInterfaceDecl *IFD = MD->getClassInterface(); -    assert(IFD); -    IFaceEnt = Entity::get(IFD, Prog); -    GlobSel = GlobalSelector::get(MD->getSelector(), Prog); -    IsInstanceMethod = MD->isInstanceMethod(); - -    for (ObjCInterfaceDecl *Cls = IFD->getSuperClass(); -           Cls; Cls = Cls->getSuperClass()) -      HierarchyEntities.insert(Entity::get(Cls, Prog)); -  } - -  virtual void Handle(TranslationUnit *TU) { -    assert(TU && "Passed null translation unit"); - -    ASTContext &Ctx = TU->getASTContext(); -    // Null means it doesn't exist in this translation unit. -    ObjCInterfaceDecl *IFace = -        cast_or_null<ObjCInterfaceDecl>(IFaceEnt.getDecl(Ctx)); -    Selector Sel = GlobSel.getSelector(Ctx); - -    SelectorMap &SelMap = TU->getSelectorMap(); -    for (SelectorMap::astlocation_iterator -           I = SelMap.refs_begin(Sel), E = SelMap.refs_end(Sel); I != E; ++I) { -      if (ValidReference(*I, IFace)) -        TULocHandler.Handle(TULocation(TU, *I)); -    } -  } - -  /// \brief Determines whether the given message expression is likely to end -  /// up at the given interface decl. -  /// -  /// It returns true "eagerly", meaning it will return false only if it can -  /// "prove" statically that the interface cannot accept this message. -  bool ValidReference(ASTLocation ASTLoc, ObjCInterfaceDecl *IFace) { -    assert(ASTLoc.isStmt()); - -    // FIXME: Finding @selector references should be through another Analyzer -    // method, like FindSelectors. -    if (isa<ObjCSelectorExpr>(ASTLoc.AsStmt())) -      return false; - -    ObjCInterfaceDecl *MsgD = 0; -    ObjCMessageExpr *Msg = cast<ObjCMessageExpr>(ASTLoc.AsStmt()); - -    switch (Msg->getReceiverKind()) { -    case ObjCMessageExpr::Instance: { -      const ObjCObjectPointerType *OPT = -          Msg->getInstanceReceiver()->getType()->getAsObjCInterfacePointerType(); - -      // Can be anything! Accept it as a possibility.. -      if (!OPT || OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()) -        return true; - -      // Expecting class method. -      if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) -        return !IsInstanceMethod; - -      MsgD = OPT->getInterfaceDecl(); -      assert(MsgD); - -      // Should be an instance method. -      if (!IsInstanceMethod) -        return false; -      break; -    } - -    case ObjCMessageExpr::Class: { -      // Expecting class method. -      if (IsInstanceMethod) -        return false; - -      MsgD = Msg->getClassReceiver()->getAs<ObjCObjectType>()->getInterface(); -      break; -    } - -    case ObjCMessageExpr::SuperClass: -      // Expecting class method. -      if (IsInstanceMethod) -        return false; - -      MsgD = Msg->getSuperType()->getAs<ObjCObjectType>()->getInterface(); -      break; - -    case ObjCMessageExpr::SuperInstance: -      // Expecting instance method. -      if (!IsInstanceMethod) -        return false; - -      MsgD = Msg->getSuperType()->getAs<ObjCObjectPointerType>() -                                                          ->getInterfaceDecl(); -      break; -    } - -    assert(MsgD); - -    // Same interface ? We have a winner! -    if (declaresSameEntity(MsgD, IFace)) -      return true; - -    // If the message interface is a superclass of the original interface, -    // accept this message as a possibility. -    if (HierarchyEntities.count(Entity::get(MsgD, Prog))) -      return true; - -    // If the message interface is a subclass of the original interface, accept -    // the message unless there is a subclass in the hierarchy that will -    // "steal" the message (thus the message "will go" to the subclass and not -    /// the original interface). -    if (IFace) { -      Selector Sel = Msg->getSelector(); -      for (ObjCInterfaceDecl *Cls = MsgD; Cls; Cls = Cls->getSuperClass()) { -        if (declaresSameEntity(Cls, IFace)) -          return true; -        if (Cls->getMethod(Sel, IsInstanceMethod)) -          return false; -      } -    } - -    // The interfaces are unrelated, don't accept the message. -    return false; -  } -}; - -//===----------------------------------------------------------------------===// -// MessageAnalyzer Implementation -//===----------------------------------------------------------------------===// - -/// \brief Accepts an ObjC message expression and finds all methods that may -/// respond to it. -class MessageAnalyzer : public TranslationUnitHandler { -  Program &Prog; -  TULocationHandler &TULocHandler; - -  // The ObjCInterface associated with the message. Can be null/invalid. -  Entity MsgIFaceEnt; -  GlobalSelector GlobSel; -  bool CanBeInstanceMethod; -  bool CanBeClassMethod; - -  /// \brief Super classes of the ObjCInterface. -  typedef llvm::SmallSet<Entity, 16> EntitiesSetTy; -  EntitiesSetTy HierarchyEntities; - -  /// \brief The interface in the message interface hierarchy that "intercepts" -  /// the selector. -  Entity ReceiverIFaceEnt; - -public: -  MessageAnalyzer(ObjCMessageExpr *Msg, -                  Program &prog, TULocationHandler &handler) -    : Prog(prog), TULocHandler(handler), -      CanBeInstanceMethod(false), -      CanBeClassMethod(false) { - -    assert(Msg); - -    ObjCInterfaceDecl *MsgD = 0; - -    while (true) { -      switch (Msg->getReceiverKind()) { -      case ObjCMessageExpr::Instance: { -        const ObjCObjectPointerType *OPT = -          Msg->getInstanceReceiver()->getType() -                                      ->getAsObjCInterfacePointerType(); - -        if (!OPT || OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()) { -          CanBeInstanceMethod = CanBeClassMethod = true; -          break; -        } - -        if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) { -          CanBeClassMethod = true; -          break; -        } - -        MsgD = OPT->getInterfaceDecl(); -        assert(MsgD); -        CanBeInstanceMethod = true; -        break; -      } -         -      case ObjCMessageExpr::Class: -        CanBeClassMethod = true; -        MsgD = Msg->getClassReceiver()->getAs<ObjCObjectType>()->getInterface(); -        break; - -      case ObjCMessageExpr::SuperClass: -        CanBeClassMethod = true; -        MsgD = Msg->getSuperType()->getAs<ObjCObjectType>()->getInterface(); -        break; - -      case ObjCMessageExpr::SuperInstance: -        CanBeInstanceMethod = true; -        MsgD = Msg->getSuperType()->getAs<ObjCObjectPointerType>() -                                                           ->getInterfaceDecl(); -        break; -      } -    } - -    assert(CanBeInstanceMethod || CanBeClassMethod); - -    Selector sel = Msg->getSelector(); -    assert(!sel.isNull()); - -    MsgIFaceEnt = Entity::get(MsgD, Prog); -    GlobSel = GlobalSelector::get(sel, Prog); - -    if (MsgD) { -      for (ObjCInterfaceDecl *Cls = MsgD->getSuperClass(); -             Cls; Cls = Cls->getSuperClass()) -        HierarchyEntities.insert(Entity::get(Cls, Prog)); - -      // Find the interface in the hierarchy that "receives" the message. -      for (ObjCInterfaceDecl *Cls = MsgD; Cls; Cls = Cls->getSuperClass()) { -        bool isReceiver = false; - -        ObjCInterfaceDecl::lookup_const_iterator Meth, MethEnd; -        for (llvm::tie(Meth, MethEnd) = Cls->lookup(sel); -               Meth != MethEnd; ++Meth) { -          if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth)) -            if ((MD->isInstanceMethod() && CanBeInstanceMethod) || -                (MD->isClassMethod()    && CanBeClassMethod)) { -              isReceiver = true; -              break; -            } -        } - -        if (isReceiver) { -          ReceiverIFaceEnt = Entity::get(Cls, Prog); -          break; -        } -      } -    } -  } - -  virtual void Handle(TranslationUnit *TU) { -    assert(TU && "Passed null translation unit"); -    ASTContext &Ctx = TU->getASTContext(); - -    // Null means it doesn't exist in this translation unit or there was no -    // interface that was determined to receive the original message. -    ObjCInterfaceDecl *ReceiverIFace = -        cast_or_null<ObjCInterfaceDecl>(ReceiverIFaceEnt.getDecl(Ctx)); - -    // No subclass for the original receiver interface, so it remains the -    // receiver. -    if (ReceiverIFaceEnt.isValid() && ReceiverIFace == 0) -      return; - -    // Null means it doesn't exist in this translation unit or there was no -    // interface associated with the message in the first place. -    ObjCInterfaceDecl *MsgIFace = -        cast_or_null<ObjCInterfaceDecl>(MsgIFaceEnt.getDecl(Ctx)); - -    Selector Sel = GlobSel.getSelector(Ctx); -    SelectorMap &SelMap = TU->getSelectorMap(); -    for (SelectorMap::method_iterator -           I = SelMap.methods_begin(Sel), E = SelMap.methods_end(Sel); -           I != E; ++I) { -      ObjCMethodDecl *D = *I; -      if (ValidMethod(D, MsgIFace, ReceiverIFace)) { -        for (ObjCMethodDecl::redecl_iterator -               RI = D->redecls_begin(), RE = D->redecls_end(); RI != RE; ++RI) -          TULocHandler.Handle(TULocation(TU, ASTLocation(*RI))); -      } -    } -  } - -  /// \brief Determines whether the given method is likely to accept the -  /// original message. -  /// -  /// It returns true "eagerly", meaning it will return false only if it can -  /// "prove" statically that the method cannot accept the original message. -  bool ValidMethod(ObjCMethodDecl *D, ObjCInterfaceDecl *MsgIFace, -                   ObjCInterfaceDecl *ReceiverIFace) { -    assert(D); - -    // FIXME: Protocol methods ? -    if (isa<ObjCProtocolDecl>(D->getDeclContext())) -      return false; - -    // No specific interface associated with the message. Can be anything. -    if (MsgIFaceEnt.isInvalid()) -      return true; - -    if ((!CanBeInstanceMethod && D->isInstanceMethod()) || -        (!CanBeClassMethod    && D->isClassMethod())) -      return false; - -    ObjCInterfaceDecl *IFace = D->getClassInterface(); -    assert(IFace); - -    // If the original message interface is the same or a superclass of the -    // given interface, accept the method as a possibility. -    if (MsgIFace && MsgIFace->isSuperClassOf(IFace)) -      return true; - -    if (ReceiverIFace) { -      // The given interface, "overrides" the receiver. -      if (ReceiverIFace->isSuperClassOf(IFace)) -        return true; -    } else { -      // No receiver was found for the original message. -      assert(ReceiverIFaceEnt.isInvalid()); - -      // If the original message interface is a subclass of the given interface, -      // accept the message. -      if (HierarchyEntities.count(Entity::get(IFace, Prog))) -        return true; -    } - -    // The interfaces are unrelated, or the receiver interface wasn't -    // "overriden". -    return false; -  } -}; - -} // end anonymous namespace - -//===----------------------------------------------------------------------===// -// Analyzer Implementation -//===----------------------------------------------------------------------===// - -void Analyzer::FindDeclarations(Decl *D, TULocationHandler &Handler) { -  assert(D && "Passed null declaration"); -  Entity Ent = Entity::get(D, Prog); -  if (Ent.isInvalid()) -    return; - -  DeclEntityAnalyzer DEA(Ent, Handler); -  Idxer.GetTranslationUnitsFor(Ent, DEA); -} - -void Analyzer::FindReferences(Decl *D, TULocationHandler &Handler) { -  assert(D && "Passed null declaration"); -  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { -    RefSelectorAnalyzer RSA(MD, Prog, Handler); -    GlobalSelector Sel = GlobalSelector::get(MD->getSelector(), Prog); -    Idxer.GetTranslationUnitsFor(Sel, RSA); -    return; -  } - -  Entity Ent = Entity::get(D, Prog); -  if (Ent.isInvalid()) -    return; - -  RefEntityAnalyzer REA(Ent, Handler); -  Idxer.GetTranslationUnitsFor(Ent, REA); -} - -/// \brief Find methods that may respond to the given message and pass them -/// to Handler. -void Analyzer::FindObjCMethods(ObjCMessageExpr *Msg, -                               TULocationHandler &Handler) { -  assert(Msg); -  MessageAnalyzer MsgAnalyz(Msg, Prog, Handler); -  GlobalSelector GlobSel = GlobalSelector::get(Msg->getSelector(), Prog); -  Idxer.GetTranslationUnitsFor(GlobSel, MsgAnalyz); -}  | 
