diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:02:28 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:02:28 +0000 |
| commit | 7442d6faa2719e4e7d33a7021c406c5a4facd74d (patch) | |
| tree | c72b9241553fc9966179aba84f90f17bfa9235c3 /lib/Index | |
| parent | b52119637f743680a99710ce5fdb6646da2772af (diff) | |
Notes
Diffstat (limited to 'lib/Index')
| -rw-r--r-- | lib/Index/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lib/Index/CommentToXML.cpp | 6 | ||||
| -rw-r--r-- | lib/Index/IndexBody.cpp | 16 | ||||
| -rw-r--r-- | lib/Index/IndexDecl.cpp | 155 | ||||
| -rw-r--r-- | lib/Index/IndexSymbol.cpp | 70 | ||||
| -rw-r--r-- | lib/Index/IndexTypeSourceInfo.cpp | 32 | ||||
| -rw-r--r-- | lib/Index/IndexingAction.cpp | 17 | ||||
| -rw-r--r-- | lib/Index/IndexingContext.cpp | 93 | ||||
| -rw-r--r-- | lib/Index/IndexingContext.h | 3 | ||||
| -rw-r--r-- | lib/Index/USRGeneration.cpp | 20 |
10 files changed, 310 insertions, 103 deletions
diff --git a/lib/Index/CMakeLists.txt b/lib/Index/CMakeLists.txt index 8f51ccb11e58..c9fbfafcf946 100644 --- a/lib/Index/CMakeLists.txt +++ b/lib/Index/CMakeLists.txt @@ -24,5 +24,6 @@ add_clang_library(clangIndex clangFormat clangFrontend clangRewrite + clangSerialization clangToolingCore ) diff --git a/lib/Index/CommentToXML.cpp b/lib/Index/CommentToXML.cpp index ee066cc6d985..08acc96c4efb 100644 --- a/lib/Index/CommentToXML.cpp +++ b/lib/Index/CommentToXML.cpp @@ -593,9 +593,11 @@ void CommentASTToXMLConverter::formatTextOfDeclaration( unsigned Length = Declaration.size(); bool IncompleteFormat = false; + format::FormatStyle Style = format::getLLVMStyle(); + Style.FixNamespaceComments = false; tooling::Replacements Replaces = - reformat(format::getLLVMStyle(), StringDecl, - tooling::Range(Offset, Length), "xmldecl.xd", &IncompleteFormat); + reformat(Style, StringDecl, tooling::Range(Offset, Length), "xmldecl.xd", + &IncompleteFormat); auto FormattedStringDecl = applyAllReplacements(StringDecl, Replaces); if (static_cast<bool>(FormattedStringDecl)) { Declaration = *FormattedStringDecl; diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp index 3aa0152ec996..7f09290de40f 100644 --- a/lib/Index/IndexBody.cpp +++ b/lib/Index/IndexBody.cpp @@ -22,6 +22,10 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> { SmallVector<Stmt*, 16> StmtStack; typedef RecursiveASTVisitor<BodyIndexer> base; + + Stmt *getParentStmt() const { + return StmtStack.size() < 2 ? nullptr : StmtStack.end()[-2]; + } public: BodyIndexer(IndexingContext &indexCtx, const NamedDecl *Parent, const DeclContext *DC) @@ -178,7 +182,8 @@ public: SymbolRoleSet Roles{}; SmallVector<SymbolRelation, 2> Relations; addCallRole(Roles, Relations); - if (E->isImplicit()) + Stmt *Containing = getParentStmt(); + if (E->isImplicit() || (Containing && isa<PseudoObjectExpr>(Containing))) Roles |= (unsigned)SymbolRole::Implicit; if (isDynamic(E)) { @@ -194,9 +199,12 @@ public: } bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { - if (E->isExplicitProperty()) + if (E->isExplicitProperty()) { + SmallVector<SymbolRelation, 2> Relations; + SymbolRoleSet Roles = getRolesForRef(E, Relations); return IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(), - Parent, ParentDC, SymbolRoleSet(), {}, E); + Parent, ParentDC, Roles, Relations, E); + } // No need to do a handleReference for the objc method, because there will // be a message expr as part of PseudoObjectExpr. @@ -269,7 +277,7 @@ public: const Decl *D = *I; if (!D) continue; - if (!IndexCtx.isFunctionLocalDecl(D)) + if (!isFunctionLocalSymbol(D)) IndexCtx.indexTopLevelDecl(D); } 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; } diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp index 84984fce4dc7..fe3c17845daa 100644 --- a/lib/Index/IndexSymbol.cpp +++ b/lib/Index/IndexSymbol.cpp @@ -49,6 +49,37 @@ static void checkForIBOutlets(const Decl *D, SymbolPropertySet &PropSet) { } } +bool index::isFunctionLocalSymbol(const Decl *D) { + assert(D); + + if (isa<ParmVarDecl>(D)) + return true; + + if (isa<TemplateTemplateParmDecl>(D)) + return true; + + if (isa<ObjCTypeParamDecl>(D)) + return true; + + if (!D->getParentFunctionOrMethod()) + return false; + + if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { + switch (ND->getFormalLinkage()) { + case NoLinkage: + case VisibleNoLinkage: + case InternalLinkage: + return true; + case UniqueExternalLinkage: + llvm_unreachable("Not a sema linkage"); + case ExternalLinkage: + return false; + } + } + + return true; +} + SymbolInfo index::getSymbolInfo(const Decl *D) { assert(D); SymbolInfo Info; @@ -57,6 +88,10 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { Info.Properties = SymbolPropertySet(); Info.Lang = SymbolLanguage::C; + if (isFunctionLocalSymbol(D)) { + Info.Properties |= (unsigned)SymbolProperty::Local; + } + if (const TagDecl *TD = dyn_cast<TagDecl>(D)) { switch (TD->getTagKind()) { case TTK_Struct: @@ -94,10 +129,13 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { } else if (auto *VD = dyn_cast<VarDecl>(D)) { Info.Kind = SymbolKind::Variable; - if (isa<CXXRecordDecl>(D->getDeclContext())) { + if (isa<ParmVarDecl>(D)) { + Info.Kind = SymbolKind::Parameter; + } else if (isa<CXXRecordDecl>(D->getDeclContext())) { Info.Kind = SymbolKind::StaticProperty; Info.Lang = SymbolLanguage::CXX; } + if (isa<VarTemplatePartialSpecializationDecl>(D)) { Info.Lang = SymbolLanguage::CXX; Info.Properties |= (unsigned)SymbolProperty::Generic; @@ -147,10 +185,18 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { Info.Lang = SymbolLanguage::ObjC; break; case Decl::ObjCCategory: - case Decl::ObjCCategoryImpl: + case Decl::ObjCCategoryImpl: { Info.Kind = SymbolKind::Extension; Info.Lang = SymbolLanguage::ObjC; + const ObjCInterfaceDecl *ClsD = nullptr; + if (auto *CatD = dyn_cast<ObjCCategoryDecl>(D)) + ClsD = CatD->getClassInterface(); + else + ClsD = cast<ObjCCategoryImplDecl>(D)->getClassInterface(); + if (isUnitTestCase(ClsD)) + Info.Properties |= (unsigned)SymbolProperty::UnitTest; break; + } case Decl::ObjCMethod: if (cast<ObjCMethodDecl>(D)->isInstanceMethod()) { const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D); @@ -275,11 +321,12 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { return Info; } -void index::applyForEachSymbolRole(SymbolRoleSet Roles, - llvm::function_ref<void(SymbolRole)> Fn) { +bool index::applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles, + llvm::function_ref<bool(SymbolRole)> Fn) { #define APPLY_FOR_ROLE(Role) \ if (Roles & (unsigned)SymbolRole::Role) \ - Fn(SymbolRole::Role) + if (!Fn(SymbolRole::Role)) \ + return false; APPLY_FOR_ROLE(Declaration); APPLY_FOR_ROLE(Definition); @@ -301,6 +348,16 @@ void index::applyForEachSymbolRole(SymbolRoleSet Roles, APPLY_FOR_ROLE(RelationIBTypeOf); #undef APPLY_FOR_ROLE + + return true; +} + +void index::applyForEachSymbolRole(SymbolRoleSet Roles, + llvm::function_ref<void(SymbolRole)> Fn) { + applyForEachSymbolRoleInterruptible(Roles, [&](SymbolRole r) -> bool { + Fn(r); + return true; + }); } void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) { @@ -378,6 +435,7 @@ StringRef index::getSymbolKindString(SymbolKind K) { case SymbolKind::Constructor: return "constructor"; case SymbolKind::Destructor: return "destructor"; case SymbolKind::ConversionFunction: return "coversion-func"; + case SymbolKind::Parameter: return "param"; } llvm_unreachable("invalid symbol kind"); } @@ -415,6 +473,7 @@ void index::applyForEachSymbolProperty(SymbolPropertySet Props, APPLY_FOR_PROPERTY(IBAnnotated); APPLY_FOR_PROPERTY(IBOutletCollection); APPLY_FOR_PROPERTY(GKInspectable); + APPLY_FOR_PROPERTY(Local); #undef APPLY_FOR_PROPERTY } @@ -434,6 +493,7 @@ void index::printSymbolProperties(SymbolPropertySet Props, raw_ostream &OS) { case SymbolProperty::IBAnnotated: OS << "IB"; break; case SymbolProperty::IBOutletCollection: OS << "IBColl"; break; case SymbolProperty::GKInspectable: OS << "GKI"; break; + case SymbolProperty::Local: OS << "local"; break; } }); } diff --git a/lib/Index/IndexTypeSourceInfo.cpp b/lib/Index/IndexTypeSourceInfo.cpp index 38bbb30fedf1..0645d5be5268 100644 --- a/lib/Index/IndexTypeSourceInfo.cpp +++ b/lib/Index/IndexTypeSourceInfo.cpp @@ -40,18 +40,36 @@ public: bool shouldWalkTypesOfTypeLocs() const { return false; } - bool VisitTypedefTypeLoc(TypedefTypeLoc TL) { - return IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(), - Parent, ParentDC, SymbolRoleSet(), - Relations); - } - #define TRY_TO(CALL_EXPR) \ do { \ if (!CALL_EXPR) \ return false; \ } while (0) + bool VisitTypedefTypeLoc(TypedefTypeLoc TL) { + SourceLocation Loc = TL.getNameLoc(); + TypedefNameDecl *ND = TL.getTypedefNameDecl(); + if (ND->isTransparentTag()) { + TagDecl *Underlying = ND->getUnderlyingType()->getAsTagDecl(); + return IndexCtx.handleReference(Underlying, Loc, Parent, + ParentDC, SymbolRoleSet(), Relations); + } + if (IsBase) { + TRY_TO(IndexCtx.handleReference(ND, Loc, + Parent, ParentDC, SymbolRoleSet())); + if (auto *CD = TL.getType()->getAsCXXRecordDecl()) { + TRY_TO(IndexCtx.handleReference(CD, Loc, Parent, ParentDC, + (unsigned)SymbolRole::Implicit, + Relations)); + } + } else { + TRY_TO(IndexCtx.handleReference(ND, Loc, + Parent, ParentDC, SymbolRoleSet(), + Relations)); + } + return true; + } + bool traverseParamVarHelper(ParmVarDecl *D) { TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); if (D->getTypeSourceInfo()) @@ -191,7 +209,7 @@ void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, } void IndexingContext::indexTagDecl(const TagDecl *D) { - if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D)) + if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D)) return; if (handleDecl(D)) { diff --git a/lib/Index/IndexingAction.cpp b/lib/Index/IndexingAction.cpp index d7442931523f..cac24d4b9c4c 100644 --- a/lib/Index/IndexingAction.cpp +++ b/lib/Index/IndexingAction.cpp @@ -13,6 +13,7 @@ #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/MultiplexConsumer.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Serialization/ASTReader.h" using namespace clang; using namespace clang::index; @@ -173,4 +174,20 @@ void index::indexASTUnit(ASTUnit &Unit, IndexCtx.setASTContext(Unit.getASTContext()); DataConsumer->initialize(Unit.getASTContext()); indexTranslationUnit(Unit, IndexCtx); + DataConsumer->finish(); +} + +void index::indexModuleFile(serialization::ModuleFile &Mod, + ASTReader &Reader, + std::shared_ptr<IndexDataConsumer> DataConsumer, + IndexingOptions Opts) { + ASTContext &Ctx = Reader.getContext(); + IndexingContext IndexCtx(Opts, *DataConsumer); + IndexCtx.setASTContext(Ctx); + DataConsumer->initialize(Ctx); + + for (const Decl *D :Reader.getModuleFileLevelDecls(Mod)) { + IndexCtx.indexTopLevelDecl(D); + } + DataConsumer->finish(); } diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp index 6dd6c0cfb28e..f393b11ab884 100644 --- a/lib/Index/IndexingContext.cpp +++ b/lib/Index/IndexingContext.cpp @@ -24,9 +24,7 @@ bool IndexingContext::shouldIndexFunctionLocalSymbols() const { bool IndexingContext::handleDecl(const Decl *D, SymbolRoleSet Roles, ArrayRef<SymbolRelation> Relations) { - return handleDeclOccurrence(D, D->getLocation(), /*IsRef=*/false, - cast<Decl>(D->getDeclContext()), Roles, Relations, - nullptr, nullptr, D->getDeclContext()); + return handleDecl(D, D->getLocation(), Roles, Relations); } bool IndexingContext::handleDecl(const Decl *D, SourceLocation Loc, @@ -35,9 +33,14 @@ bool IndexingContext::handleDecl(const Decl *D, SourceLocation Loc, const DeclContext *DC) { if (!DC) DC = D->getDeclContext(); + + const Decl *OrigD = D; + if (isa<ObjCPropertyImplDecl>(D)) { + D = cast<ObjCPropertyImplDecl>(D)->getPropertyDecl(); + } return handleDeclOccurrence(D, Loc, /*IsRef=*/false, cast<Decl>(DC), Roles, Relations, - nullptr, nullptr, DC); + nullptr, OrigD, DC); } bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc, @@ -47,7 +50,7 @@ bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc, ArrayRef<SymbolRelation> Relations, const Expr *RefE, const Decl *RefD) { - if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D)) + if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D)) return true; if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D)) @@ -97,34 +100,6 @@ bool IndexingContext::importedModule(const ImportDecl *ImportD) { return DataConsumer.handleModuleOccurence(ImportD, Roles, FID, Offset); } -bool IndexingContext::isFunctionLocalDecl(const Decl *D) { - assert(D); - - if (isa<TemplateTemplateParmDecl>(D)) - return true; - - if (isa<ObjCTypeParamDecl>(D)) - return true; - - if (!D->getParentFunctionOrMethod()) - return false; - - if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { - switch (ND->getFormalLinkage()) { - case NoLinkage: - case VisibleNoLinkage: - case InternalLinkage: - return true; - case UniqueExternalLinkage: - llvm_unreachable("Not a sema linkage"); - case ExternalLinkage: - return false; - } - } - - return true; -} - bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) { TemplateSpecializationKind TKind = TSK_Undeclared; if (const ClassTemplateSpecializationDecl * @@ -229,6 +204,50 @@ static const Decl *getCanonicalDecl(const Decl *D) { return D; } +static bool shouldReportOccurrenceForSystemDeclOnlyMode( + bool IsRef, SymbolRoleSet Roles, ArrayRef<SymbolRelation> Relations) { + if (!IsRef) + return true; + + auto acceptForRelation = [](SymbolRoleSet roles) -> bool { + bool accept = false; + applyForEachSymbolRoleInterruptible(roles, [&accept](SymbolRole r) -> bool { + switch (r) { + case SymbolRole::RelationChildOf: + case SymbolRole::RelationBaseOf: + case SymbolRole::RelationOverrideOf: + case SymbolRole::RelationExtendedBy: + case SymbolRole::RelationAccessorOf: + case SymbolRole::RelationIBTypeOf: + accept = true; + return false; + case SymbolRole::Declaration: + case SymbolRole::Definition: + case SymbolRole::Reference: + case SymbolRole::Read: + case SymbolRole::Write: + case SymbolRole::Call: + case SymbolRole::Dynamic: + case SymbolRole::AddressOf: + case SymbolRole::Implicit: + case SymbolRole::RelationReceivedBy: + case SymbolRole::RelationCalledBy: + case SymbolRole::RelationContainedBy: + return true; + } + llvm_unreachable("Unsupported SymbolRole value!"); + }); + return accept; + }; + + for (auto &Rel : Relations) { + if (acceptForRelation(Rel.Roles)) + return true; + } + + return false; +} + bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc, bool IsRef, const Decl *Parent, SymbolRoleSet Roles, @@ -264,7 +283,7 @@ bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc, case IndexingOptions::SystemSymbolFilterKind::None: return true; case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly: - if (IsRef) + if (!shouldReportOccurrenceForSystemDeclOnlyMode(IsRef, Roles, Relations)) return true; break; case IndexingOptions::SystemSymbolFilterKind::All: @@ -286,7 +305,7 @@ bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc, if (IsRef) Roles |= (unsigned)SymbolRole::Reference; - else if (isDeclADefinition(D, ContainerDC, *Ctx)) + else if (isDeclADefinition(OrigD, ContainerDC, *Ctx)) Roles |= (unsigned)SymbolRole::Definition; else Roles |= (unsigned)SymbolRole::Declaration; @@ -313,12 +332,12 @@ bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc, }; if (Parent) { - if (IsRef) { + if (IsRef || (!isa<ParmVarDecl>(D) && isFunctionLocalSymbol(D))) { addRelation(SymbolRelation{ (unsigned)SymbolRole::RelationContainedBy, Parent }); - } else if (!cast<DeclContext>(Parent)->isFunctionOrMethod()) { + } else { addRelation(SymbolRelation{ (unsigned)SymbolRole::RelationChildOf, Parent diff --git a/lib/Index/IndexingContext.h b/lib/Index/IndexingContext.h index dd1dd328cd44..933b0a2cda07 100644 --- a/lib/Index/IndexingContext.h +++ b/lib/Index/IndexingContext.h @@ -58,7 +58,6 @@ public: return false; } - static bool isFunctionLocalDecl(const Decl *D); static bool isTemplateImplicitInstantiation(const Decl *D); bool handleDecl(const Decl *D, SymbolRoleSet Roles = SymbolRoleSet(), @@ -72,7 +71,7 @@ public: bool handleReference(const NamedDecl *D, SourceLocation Loc, const NamedDecl *Parent, const DeclContext *DC, - SymbolRoleSet Roles, + SymbolRoleSet Roles = SymbolRoleSet(), ArrayRef<SymbolRelation> Relations = None, const Expr *RefE = nullptr, const Decl *RefD = nullptr); diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp index 58f61c3c65b7..73dddd9a8b36 100644 --- a/lib/Index/USRGeneration.cpp +++ b/lib/Index/USRGeneration.cpp @@ -310,7 +310,7 @@ void USRGenerator::VisitVarDecl(const VarDecl *D) { // For a template specialization, mangle the template arguments. if (const VarTemplateSpecializationDecl *Spec = dyn_cast<VarTemplateSpecializationDecl>(D)) { - const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs(); + const TemplateArgumentList &Args = Spec->getTemplateArgs(); Out << '>'; for (unsigned I = 0, N = Args.size(); I != N; ++I) { Out << '#'; @@ -521,7 +521,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) { // For a class template specialization, mangle the template arguments. if (const ClassTemplateSpecializationDecl *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) { - const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs(); + const TemplateArgumentList &Args = Spec->getTemplateArgs(); Out << '>'; for (unsigned I = 0, N = Args.size(); I != N; ++I) { Out << '#'; @@ -654,7 +654,6 @@ void USRGenerator::VisitType(QualType T) { case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: - case BuiltinType::OCLNDRange: case BuiltinType::OCLReserveID: case BuiltinType::OCLSampler: IgnoreResults = true; @@ -911,21 +910,30 @@ bool clang::index::generateUSRForDecl(const Decl *D, bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD, const SourceManager &SM, SmallVectorImpl<char> &Buf) { + if (!MD) + return true; + return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(), + SM, Buf); + +} + +bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc, + const SourceManager &SM, + SmallVectorImpl<char> &Buf) { // Don't generate USRs for things with invalid locations. - if (!MD || MD->getLocation().isInvalid()) + if (MacroName.empty() || Loc.isInvalid()) return true; llvm::raw_svector_ostream Out(Buf); // Assume that system headers are sane. Don't put source location // information into the USR if the macro comes from a system header. - SourceLocation Loc = MD->getLocation(); bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc); Out << getUSRSpacePrefix(); if (ShouldGenerateLocation) printLoc(Out, Loc, SM, /*IncludeOffset=*/true); Out << "@macro@"; - Out << MD->getName()->getName(); + Out << MacroName; return false; } |
