diff options
Diffstat (limited to 'lib/Index/IndexDecl.cpp')
| -rw-r--r-- | lib/Index/IndexDecl.cpp | 155 | 
1 files changed, 115 insertions, 40 deletions
diff --git a/lib/Index/IndexDecl.cpp b/lib/Index/IndexDecl.cpp index 3b4f3f81399d..dae0cdc0d9c9 100644 --- a/lib/Index/IndexDecl.cpp +++ b/lib/Index/IndexDecl.cpp @@ -98,7 +98,29 @@ public:      if (MethodLoc.isInvalid())        MethodLoc = D->getLocation(); -    if (!IndexCtx.handleDecl(D, MethodLoc, (unsigned)SymbolRole::Dynamic, Relations)) +    SourceLocation AttrLoc; + +    // check for (getter=/setter=) +    if (AssociatedProp) { +      bool isGetter = !D->param_size(); +      AttrLoc = isGetter ? +        AssociatedProp->getGetterNameLoc(): +        AssociatedProp->getSetterNameLoc(); +    } + +    SymbolRoleSet Roles = (SymbolRoleSet)SymbolRole::Dynamic; +    if (D->isImplicit()) { +      if (AttrLoc.isValid()) { +        MethodLoc = AttrLoc; +      } else { +        Roles |= (SymbolRoleSet)SymbolRole::Implicit; +      } +    } else if (AttrLoc.isValid()) { +      IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()), +                               D->getDeclContext(), 0); +    } + +    if (!IndexCtx.handleDecl(D, MethodLoc, Roles, Relations))        return false;      IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);      bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>(); @@ -136,6 +158,9 @@ public:      handleDeclarator(D);      if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) { +      IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(), +                               Ctor->getParent(), Ctor->getDeclContext()); +        // Constructor initializers.        for (const auto *Init : Ctor->inits()) {          if (Init->isWritten()) { @@ -146,6 +171,12 @@ public:            IndexCtx.indexBody(Init->getInit(), D, D);          }        } +    } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) { +      if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) { +        IndexCtx.handleReference(Dtor->getParent(), +                                 TypeNameInfo->getTypeLoc().getLocStart(), +                                 Dtor->getParent(), Dtor->getDeclContext()); +      }      }      if (D->isThisDeclarationADefinition()) { @@ -178,14 +209,8 @@ public:    bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {      if (D->getSynthesize()) { -      // For synthesized ivars, use the location of the ObjC implementation, -      // not the location of the property. -      // Otherwise the header file containing the @interface will have different -      // indexing contents based on whether the @implementation was present or -      // not in the translation unit. -      return IndexCtx.handleDecl(D, -                                 cast<Decl>(D->getDeclContext())->getLocation(), -                                 (unsigned)SymbolRole::Implicit); +      // handled in VisitObjCPropertyImplDecl +      return true;      }      if (!IndexCtx.handleDecl(D))        return false; @@ -206,8 +231,9 @@ public:    }    bool VisitTypedefNameDecl(const TypedefNameDecl *D) { -    if (!IndexCtx.handleDecl(D)) -      return false; +    if (!D->isTransparentTag()) +      if (!IndexCtx.handleDecl(D)) +        return false;      IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);      return true;    } @@ -228,14 +254,17 @@ public:    }    bool handleReferencedProtocols(const ObjCProtocolList &ProtList, -                                 const ObjCContainerDecl *ContD) { +                                 const ObjCContainerDecl *ContD, +                                 SourceLocation SuperLoc) {      ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();      for (ObjCInterfaceDecl::protocol_iterator           I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {        SourceLocation Loc = *LI;        ObjCProtocolDecl *PD = *I; -      TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, -          SymbolRoleSet(), +      SymbolRoleSet roles{}; +      if (Loc == SuperLoc) +        roles |= (SymbolRoleSet)SymbolRole::Implicit; +      TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,            SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));      }      return true; @@ -244,12 +273,26 @@ public:    bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {      if (D->isThisDeclarationADefinition()) {        TRY_TO(IndexCtx.handleDecl(D)); +      SourceLocation SuperLoc = D->getSuperClassLoc();        if (auto *SuperD = D->getSuperClass()) { -        TRY_TO(IndexCtx.handleReference(SuperD, D->getSuperClassLoc(), D, D, -            SymbolRoleSet(), +        bool hasSuperTypedef = false; +        if (auto *TInfo = D->getSuperClassTInfo()) { +          if (auto *TT = TInfo->getType()->getAs<TypedefType>()) { +            if (auto *TD = TT->getDecl()) { +              hasSuperTypedef = true; +              TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D, +                                              SymbolRoleSet())); +            } +          } +        } +        SymbolRoleSet superRoles{}; +        if (hasSuperTypedef) +          superRoles |= (SymbolRoleSet)SymbolRole::Implicit; +        TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,              SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));        } -      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D)); +      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D, +                                       SuperLoc));        TRY_TO(IndexCtx.indexDeclContext(D));      } else {        return IndexCtx.handleReference(D, D->getLocation(), nullptr, @@ -261,7 +304,8 @@ public:    bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {      if (D->isThisDeclarationADefinition()) {        TRY_TO(IndexCtx.handleDecl(D)); -      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D)); +      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D, +                                       /*superLoc=*/SourceLocation()));        TRY_TO(IndexCtx.indexDeclContext(D));      } else {        return IndexCtx.handleReference(D, D->getLocation(), nullptr, @@ -281,12 +325,16 @@ public:      if (!IndexCtx.handleDecl(D))        return false; -    // Index the ivars first to make sure the synthesized ivars are indexed -    // before indexing the methods that can reference them. -    for (const auto *IvarI : D->ivars()) -      IndexCtx.indexDecl(IvarI); +    // Visit implicit @synthesize property implementations first as their +    // location is reported at the name of the @implementation block. This +    // serves no purpose other than to simplify the FileCheck-based tests. +    for (const auto *I : D->property_impls()) { +      if (I->getLocation().isInvalid()) +        IndexCtx.indexDecl(I); +    }      for (const auto *I : D->decls()) { -      if (!isa<ObjCIvarDecl>(I)) +      if (!isa<ObjCPropertyImplDecl>(I) || +          cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())          IndexCtx.indexDecl(I);      } @@ -305,7 +353,8 @@ public:      if (!CategoryLoc.isValid())        CategoryLoc = D->getLocation();      TRY_TO(IndexCtx.handleDecl(D, CategoryLoc)); -    TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D)); +    TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D, +                                     /*superLoc=*/SourceLocation()));      TRY_TO(IndexCtx.indexDeclContext(D));      return true;    } @@ -355,32 +404,58 @@ public:    bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {      ObjCPropertyDecl *PD = D->getPropertyDecl(); -    if (!IndexCtx.handleReference(PD, D->getLocation(), -                             /*Parent=*/cast<NamedDecl>(D->getDeclContext()), -                             D->getDeclContext(), SymbolRoleSet(), {}, -                             /*RefE=*/nullptr, D)) +    auto *Container = cast<ObjCImplDecl>(D->getDeclContext()); +    SourceLocation Loc = D->getLocation(); +    SymbolRoleSet Roles = 0; +    SmallVector<SymbolRelation, 1> Relations; + +    if (ObjCIvarDecl *ID = D->getPropertyIvarDecl()) +      Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID}); +    if (Loc.isInvalid()) { +      Loc = Container->getLocation(); +      Roles |= (SymbolRoleSet)SymbolRole::Implicit; +    } +    if (!IndexCtx.handleDecl(D, Loc, Roles, Relations))        return false;      if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)        return true; -    assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize); -     -    if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) { -      if (!IvarD->getSynthesize()) -        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr, -                                 D->getDeclContext(), SymbolRoleSet()); -    } -    auto *ImplD = cast<ObjCImplDecl>(D->getDeclContext()); +    assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);      if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {        if (MD->isPropertyAccessor() && -          !hasUserDefined(MD, ImplD)) -        IndexCtx.handleDecl(MD, D->getLocation(), SymbolRoleSet(), {}, ImplD); +          !hasUserDefined(MD, Container)) +        IndexCtx.handleDecl(MD, Loc, SymbolRoleSet(SymbolRole::Implicit), {}, +                            Container);      }      if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {        if (MD->isPropertyAccessor() && -          !hasUserDefined(MD, ImplD)) -        IndexCtx.handleDecl(MD, D->getLocation(), SymbolRoleSet(), {}, ImplD); +          !hasUserDefined(MD, Container)) +        IndexCtx.handleDecl(MD, Loc, SymbolRoleSet(SymbolRole::Implicit), {}, +                            Container); +    } +    if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) { +      if (IvarD->getSynthesize()) { +        // For synthesized ivars, use the location of its name in the +        // corresponding @synthesize. If there isn't one, use the containing +        // @implementation's location, rather than the property's location, +        // otherwise the header file containing the @interface will have different +        // indexing contents based on whether the @implementation was present or +        // not in the translation unit. +        SymbolRoleSet IvarRoles = 0; +        SourceLocation IvarLoc = D->getPropertyIvarDeclLoc(); +        if (D->getLocation().isInvalid()) { +          IvarLoc = Container->getLocation(); +          IvarRoles = (SymbolRoleSet)SymbolRole::Implicit; +        } else if (D->getLocation() == IvarLoc) { +          IvarRoles = (SymbolRoleSet)SymbolRole::Implicit; +        } +        if(!IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles)) +          return false; +      } else { +        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr, +                                 D->getDeclContext(), SymbolRoleSet()); +      }      }      return true;    }  | 
