17330f729Sjoerg //===--- IndexSymbol.cpp - Types and functions for indexing symbols -------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg
97330f729Sjoerg #include "clang/Index/IndexSymbol.h"
10*e038c9c4Sjoerg #include "clang/AST/Attr.h"
117330f729Sjoerg #include "clang/AST/DeclCXX.h"
127330f729Sjoerg #include "clang/AST/DeclObjC.h"
137330f729Sjoerg #include "clang/AST/DeclTemplate.h"
147330f729Sjoerg #include "clang/AST/PrettyPrinter.h"
157330f729Sjoerg #include "clang/Lex/MacroInfo.h"
167330f729Sjoerg
177330f729Sjoerg using namespace clang;
187330f729Sjoerg using namespace clang::index;
197330f729Sjoerg
207330f729Sjoerg /// \returns true if \c D is a subclass of 'XCTestCase'.
isUnitTestCase(const ObjCInterfaceDecl * D)217330f729Sjoerg static bool isUnitTestCase(const ObjCInterfaceDecl *D) {
227330f729Sjoerg if (!D)
237330f729Sjoerg return false;
247330f729Sjoerg while (const ObjCInterfaceDecl *SuperD = D->getSuperClass()) {
257330f729Sjoerg if (SuperD->getName() == "XCTestCase")
267330f729Sjoerg return true;
277330f729Sjoerg D = SuperD;
287330f729Sjoerg }
297330f729Sjoerg return false;
307330f729Sjoerg }
317330f729Sjoerg
327330f729Sjoerg /// \returns true if \c D is in a subclass of 'XCTestCase', returns void, has
337330f729Sjoerg /// no parameters, and its name starts with 'test'.
isUnitTest(const ObjCMethodDecl * D)347330f729Sjoerg static bool isUnitTest(const ObjCMethodDecl *D) {
357330f729Sjoerg if (!D->parameters().empty())
367330f729Sjoerg return false;
377330f729Sjoerg if (!D->getReturnType()->isVoidType())
387330f729Sjoerg return false;
397330f729Sjoerg if (!D->getSelector().getNameForSlot(0).startswith("test"))
407330f729Sjoerg return false;
417330f729Sjoerg return isUnitTestCase(D->getClassInterface());
427330f729Sjoerg }
437330f729Sjoerg
checkForIBOutlets(const Decl * D,SymbolPropertySet & PropSet)447330f729Sjoerg static void checkForIBOutlets(const Decl *D, SymbolPropertySet &PropSet) {
457330f729Sjoerg if (D->hasAttr<IBOutletAttr>()) {
467330f729Sjoerg PropSet |= (SymbolPropertySet)SymbolProperty::IBAnnotated;
477330f729Sjoerg } else if (D->hasAttr<IBOutletCollectionAttr>()) {
487330f729Sjoerg PropSet |= (SymbolPropertySet)SymbolProperty::IBAnnotated;
497330f729Sjoerg PropSet |= (SymbolPropertySet)SymbolProperty::IBOutletCollection;
507330f729Sjoerg }
517330f729Sjoerg }
527330f729Sjoerg
isFunctionLocalSymbol(const Decl * D)537330f729Sjoerg bool index::isFunctionLocalSymbol(const Decl *D) {
547330f729Sjoerg assert(D);
557330f729Sjoerg
567330f729Sjoerg if (isa<ParmVarDecl>(D))
577330f729Sjoerg return true;
587330f729Sjoerg
597330f729Sjoerg if (isa<ObjCTypeParamDecl>(D))
607330f729Sjoerg return true;
617330f729Sjoerg
627330f729Sjoerg if (isa<UsingDirectiveDecl>(D))
637330f729Sjoerg return false;
647330f729Sjoerg if (!D->getParentFunctionOrMethod())
657330f729Sjoerg return false;
667330f729Sjoerg
677330f729Sjoerg if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
687330f729Sjoerg switch (ND->getFormalLinkage()) {
697330f729Sjoerg case NoLinkage:
707330f729Sjoerg case InternalLinkage:
717330f729Sjoerg return true;
727330f729Sjoerg case VisibleNoLinkage:
737330f729Sjoerg case UniqueExternalLinkage:
747330f729Sjoerg case ModuleInternalLinkage:
757330f729Sjoerg llvm_unreachable("Not a sema linkage");
767330f729Sjoerg case ModuleLinkage:
777330f729Sjoerg case ExternalLinkage:
787330f729Sjoerg return false;
797330f729Sjoerg }
807330f729Sjoerg }
817330f729Sjoerg
827330f729Sjoerg return true;
837330f729Sjoerg }
847330f729Sjoerg
getSymbolInfo(const Decl * D)857330f729Sjoerg SymbolInfo index::getSymbolInfo(const Decl *D) {
867330f729Sjoerg assert(D);
877330f729Sjoerg SymbolInfo Info;
887330f729Sjoerg Info.Kind = SymbolKind::Unknown;
897330f729Sjoerg Info.SubKind = SymbolSubKind::None;
907330f729Sjoerg Info.Properties = SymbolPropertySet();
917330f729Sjoerg Info.Lang = SymbolLanguage::C;
927330f729Sjoerg
937330f729Sjoerg if (isFunctionLocalSymbol(D)) {
947330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Local;
957330f729Sjoerg }
967330f729Sjoerg if (isa<ObjCProtocolDecl>(D->getDeclContext())) {
977330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::ProtocolInterface;
987330f729Sjoerg }
997330f729Sjoerg
1007330f729Sjoerg if (auto *VT = dyn_cast<VarTemplateDecl>(D)) {
1017330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1027330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
1037330f729Sjoerg // All other fields are filled from the templated decl.
1047330f729Sjoerg D = VT->getTemplatedDecl();
1057330f729Sjoerg }
1067330f729Sjoerg
1077330f729Sjoerg if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
1087330f729Sjoerg switch (TD->getTagKind()) {
1097330f729Sjoerg case TTK_Struct:
1107330f729Sjoerg Info.Kind = SymbolKind::Struct; break;
1117330f729Sjoerg case TTK_Union:
1127330f729Sjoerg Info.Kind = SymbolKind::Union; break;
1137330f729Sjoerg case TTK_Class:
1147330f729Sjoerg Info.Kind = SymbolKind::Class;
1157330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
1167330f729Sjoerg break;
1177330f729Sjoerg case TTK_Interface:
1187330f729Sjoerg Info.Kind = SymbolKind::Protocol;
1197330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
1207330f729Sjoerg break;
1217330f729Sjoerg case TTK_Enum:
1227330f729Sjoerg Info.Kind = SymbolKind::Enum; break;
1237330f729Sjoerg }
1247330f729Sjoerg
1257330f729Sjoerg if (const CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(D)) {
1267330f729Sjoerg if (!CXXRec->isCLike()) {
1277330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
1287330f729Sjoerg if (CXXRec->getDescribedClassTemplate()) {
1297330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1307330f729Sjoerg }
1317330f729Sjoerg }
1327330f729Sjoerg }
1337330f729Sjoerg
1347330f729Sjoerg if (isa<ClassTemplatePartialSpecializationDecl>(D)) {
1357330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1367330f729Sjoerg Info.Properties |=
1377330f729Sjoerg (SymbolPropertySet)SymbolProperty::TemplatePartialSpecialization;
1387330f729Sjoerg } else if (isa<ClassTemplateSpecializationDecl>(D)) {
1397330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1407330f729Sjoerg Info.Properties |=
1417330f729Sjoerg (SymbolPropertySet)SymbolProperty::TemplateSpecialization;
1427330f729Sjoerg }
1437330f729Sjoerg
1447330f729Sjoerg } else if (auto *VD = dyn_cast<VarDecl>(D)) {
1457330f729Sjoerg Info.Kind = SymbolKind::Variable;
1467330f729Sjoerg if (isa<ParmVarDecl>(D)) {
1477330f729Sjoerg Info.Kind = SymbolKind::Parameter;
1487330f729Sjoerg } else if (isa<CXXRecordDecl>(D->getDeclContext())) {
1497330f729Sjoerg Info.Kind = SymbolKind::StaticProperty;
1507330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
1517330f729Sjoerg }
1527330f729Sjoerg
1537330f729Sjoerg if (isa<VarTemplatePartialSpecializationDecl>(D)) {
1547330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
1557330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1567330f729Sjoerg Info.Properties |=
1577330f729Sjoerg (SymbolPropertySet)SymbolProperty::TemplatePartialSpecialization;
1587330f729Sjoerg } else if (isa<VarTemplateSpecializationDecl>(D)) {
1597330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
1607330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1617330f729Sjoerg Info.Properties |=
1627330f729Sjoerg (SymbolPropertySet)SymbolProperty::TemplateSpecialization;
1637330f729Sjoerg } else if (VD->getDescribedVarTemplate()) {
1647330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
1657330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1667330f729Sjoerg }
1677330f729Sjoerg
1687330f729Sjoerg } else {
1697330f729Sjoerg switch (D->getKind()) {
1707330f729Sjoerg case Decl::Import:
1717330f729Sjoerg Info.Kind = SymbolKind::Module;
1727330f729Sjoerg break;
1737330f729Sjoerg case Decl::Typedef:
1747330f729Sjoerg Info.Kind = SymbolKind::TypeAlias; break; // Lang = C
1757330f729Sjoerg case Decl::Function:
1767330f729Sjoerg Info.Kind = SymbolKind::Function;
1777330f729Sjoerg break;
1787330f729Sjoerg case Decl::Field:
1797330f729Sjoerg case Decl::IndirectField:
1807330f729Sjoerg Info.Kind = SymbolKind::Field;
1817330f729Sjoerg if (const CXXRecordDecl *
1827330f729Sjoerg CXXRec = dyn_cast<CXXRecordDecl>(D->getDeclContext())) {
1837330f729Sjoerg if (!CXXRec->isCLike())
1847330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
1857330f729Sjoerg }
1867330f729Sjoerg break;
1877330f729Sjoerg case Decl::EnumConstant:
1887330f729Sjoerg Info.Kind = SymbolKind::EnumConstant; break;
1897330f729Sjoerg case Decl::ObjCInterface:
1907330f729Sjoerg case Decl::ObjCImplementation: {
1917330f729Sjoerg Info.Kind = SymbolKind::Class;
1927330f729Sjoerg Info.Lang = SymbolLanguage::ObjC;
1937330f729Sjoerg const ObjCInterfaceDecl *ClsD = dyn_cast<ObjCInterfaceDecl>(D);
1947330f729Sjoerg if (!ClsD)
1957330f729Sjoerg ClsD = cast<ObjCImplementationDecl>(D)->getClassInterface();
1967330f729Sjoerg if (isUnitTestCase(ClsD))
1977330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::UnitTest;
1987330f729Sjoerg break;
1997330f729Sjoerg }
2007330f729Sjoerg case Decl::ObjCProtocol:
2017330f729Sjoerg Info.Kind = SymbolKind::Protocol;
2027330f729Sjoerg Info.Lang = SymbolLanguage::ObjC;
2037330f729Sjoerg break;
2047330f729Sjoerg case Decl::ObjCCategory:
2057330f729Sjoerg case Decl::ObjCCategoryImpl: {
2067330f729Sjoerg Info.Kind = SymbolKind::Extension;
2077330f729Sjoerg Info.Lang = SymbolLanguage::ObjC;
2087330f729Sjoerg const ObjCInterfaceDecl *ClsD = nullptr;
2097330f729Sjoerg if (auto *CatD = dyn_cast<ObjCCategoryDecl>(D))
2107330f729Sjoerg ClsD = CatD->getClassInterface();
2117330f729Sjoerg else
2127330f729Sjoerg ClsD = cast<ObjCCategoryImplDecl>(D)->getClassInterface();
2137330f729Sjoerg if (isUnitTestCase(ClsD))
2147330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::UnitTest;
2157330f729Sjoerg break;
2167330f729Sjoerg }
2177330f729Sjoerg case Decl::ObjCMethod: {
2187330f729Sjoerg const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
2197330f729Sjoerg Info.Kind = MD->isInstanceMethod() ? SymbolKind::InstanceMethod : SymbolKind::ClassMethod;
2207330f729Sjoerg if (MD->isPropertyAccessor()) {
2217330f729Sjoerg if (MD->param_size())
2227330f729Sjoerg Info.SubKind = SymbolSubKind::AccessorSetter;
2237330f729Sjoerg else
2247330f729Sjoerg Info.SubKind = SymbolSubKind::AccessorGetter;
2257330f729Sjoerg }
2267330f729Sjoerg Info.Lang = SymbolLanguage::ObjC;
2277330f729Sjoerg if (isUnitTest(MD))
2287330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::UnitTest;
2297330f729Sjoerg if (D->hasAttr<IBActionAttr>())
2307330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::IBAnnotated;
2317330f729Sjoerg break;
2327330f729Sjoerg }
2337330f729Sjoerg case Decl::ObjCProperty:
2347330f729Sjoerg Info.Kind = SymbolKind::InstanceProperty;
2357330f729Sjoerg Info.Lang = SymbolLanguage::ObjC;
2367330f729Sjoerg checkForIBOutlets(D, Info.Properties);
2377330f729Sjoerg if (auto *Annot = D->getAttr<AnnotateAttr>()) {
2387330f729Sjoerg if (Annot->getAnnotation() == "gk_inspectable")
2397330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::GKInspectable;
2407330f729Sjoerg }
2417330f729Sjoerg break;
2427330f729Sjoerg case Decl::ObjCIvar:
2437330f729Sjoerg Info.Kind = SymbolKind::Field;
2447330f729Sjoerg Info.Lang = SymbolLanguage::ObjC;
2457330f729Sjoerg checkForIBOutlets(D, Info.Properties);
2467330f729Sjoerg break;
2477330f729Sjoerg case Decl::Namespace:
2487330f729Sjoerg Info.Kind = SymbolKind::Namespace;
2497330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
2507330f729Sjoerg break;
2517330f729Sjoerg case Decl::NamespaceAlias:
2527330f729Sjoerg Info.Kind = SymbolKind::NamespaceAlias;
2537330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
2547330f729Sjoerg break;
2557330f729Sjoerg case Decl::CXXConstructor: {
2567330f729Sjoerg Info.Kind = SymbolKind::Constructor;
2577330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
2587330f729Sjoerg auto *CD = cast<CXXConstructorDecl>(D);
2597330f729Sjoerg if (CD->isCopyConstructor())
2607330f729Sjoerg Info.SubKind = SymbolSubKind::CXXCopyConstructor;
2617330f729Sjoerg else if (CD->isMoveConstructor())
2627330f729Sjoerg Info.SubKind = SymbolSubKind::CXXMoveConstructor;
2637330f729Sjoerg break;
2647330f729Sjoerg }
2657330f729Sjoerg case Decl::CXXDestructor:
2667330f729Sjoerg Info.Kind = SymbolKind::Destructor;
2677330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
2687330f729Sjoerg break;
2697330f729Sjoerg case Decl::CXXConversion:
2707330f729Sjoerg Info.Kind = SymbolKind::ConversionFunction;
2717330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
2727330f729Sjoerg break;
2737330f729Sjoerg case Decl::CXXMethod: {
2747330f729Sjoerg const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
2757330f729Sjoerg if (MD->isStatic())
2767330f729Sjoerg Info.Kind = SymbolKind::StaticMethod;
2777330f729Sjoerg else
2787330f729Sjoerg Info.Kind = SymbolKind::InstanceMethod;
2797330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
2807330f729Sjoerg break;
2817330f729Sjoerg }
2827330f729Sjoerg case Decl::ClassTemplate:
2837330f729Sjoerg Info.Kind = SymbolKind::Class;
2847330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
2857330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
2867330f729Sjoerg break;
2877330f729Sjoerg case Decl::FunctionTemplate:
2887330f729Sjoerg Info.Kind = SymbolKind::Function;
2897330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
2907330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
2917330f729Sjoerg if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(
2927330f729Sjoerg cast<FunctionTemplateDecl>(D)->getTemplatedDecl())) {
2937330f729Sjoerg if (isa<CXXConstructorDecl>(MD))
2947330f729Sjoerg Info.Kind = SymbolKind::Constructor;
2957330f729Sjoerg else if (isa<CXXDestructorDecl>(MD))
2967330f729Sjoerg Info.Kind = SymbolKind::Destructor;
2977330f729Sjoerg else if (isa<CXXConversionDecl>(MD))
2987330f729Sjoerg Info.Kind = SymbolKind::ConversionFunction;
2997330f729Sjoerg else {
3007330f729Sjoerg if (MD->isStatic())
3017330f729Sjoerg Info.Kind = SymbolKind::StaticMethod;
3027330f729Sjoerg else
3037330f729Sjoerg Info.Kind = SymbolKind::InstanceMethod;
3047330f729Sjoerg }
3057330f729Sjoerg }
3067330f729Sjoerg break;
3077330f729Sjoerg case Decl::TypeAliasTemplate:
3087330f729Sjoerg Info.Kind = SymbolKind::TypeAlias;
3097330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
3107330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
3117330f729Sjoerg break;
3127330f729Sjoerg case Decl::TypeAlias:
3137330f729Sjoerg Info.Kind = SymbolKind::TypeAlias;
3147330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
3157330f729Sjoerg break;
3167330f729Sjoerg case Decl::UnresolvedUsingTypename:
3177330f729Sjoerg Info.Kind = SymbolKind::Using;
3187330f729Sjoerg Info.SubKind = SymbolSubKind::UsingTypename;
3197330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
3207330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
3217330f729Sjoerg break;
3227330f729Sjoerg case Decl::UnresolvedUsingValue:
3237330f729Sjoerg Info.Kind = SymbolKind::Using;
3247330f729Sjoerg Info.SubKind = SymbolSubKind::UsingValue;
3257330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
3267330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
3277330f729Sjoerg break;
3287330f729Sjoerg case Decl::Using:
3297330f729Sjoerg Info.Kind = SymbolKind::Using;
3307330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
3317330f729Sjoerg break;
3327330f729Sjoerg case Decl::Binding:
3337330f729Sjoerg Info.Kind = SymbolKind::Variable;
3347330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
3357330f729Sjoerg break;
3367330f729Sjoerg case Decl::MSProperty:
3377330f729Sjoerg Info.Kind = SymbolKind::InstanceProperty;
3387330f729Sjoerg if (const CXXRecordDecl *CXXRec =
3397330f729Sjoerg dyn_cast<CXXRecordDecl>(D->getDeclContext())) {
3407330f729Sjoerg if (!CXXRec->isCLike())
3417330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
3427330f729Sjoerg }
3437330f729Sjoerg break;
3447330f729Sjoerg case Decl::ClassTemplatePartialSpecialization:
3457330f729Sjoerg case Decl::ClassScopeFunctionSpecialization:
3467330f729Sjoerg case Decl::ClassTemplateSpecialization:
3477330f729Sjoerg case Decl::CXXRecord:
3487330f729Sjoerg case Decl::Enum:
3497330f729Sjoerg case Decl::Record:
3507330f729Sjoerg llvm_unreachable("records handled before");
3517330f729Sjoerg break;
3527330f729Sjoerg case Decl::VarTemplateSpecialization:
3537330f729Sjoerg case Decl::VarTemplatePartialSpecialization:
3547330f729Sjoerg case Decl::ImplicitParam:
3557330f729Sjoerg case Decl::ParmVar:
3567330f729Sjoerg case Decl::Var:
3577330f729Sjoerg case Decl::VarTemplate:
3587330f729Sjoerg llvm_unreachable("variables handled before");
3597330f729Sjoerg break;
360*e038c9c4Sjoerg case Decl::TemplateTypeParm:
361*e038c9c4Sjoerg Info.Kind = SymbolKind::TemplateTypeParm;
362*e038c9c4Sjoerg break;
363*e038c9c4Sjoerg case Decl::TemplateTemplateParm:
364*e038c9c4Sjoerg Info.Kind = SymbolKind::TemplateTemplateParm;
365*e038c9c4Sjoerg break;
366*e038c9c4Sjoerg case Decl::NonTypeTemplateParm:
367*e038c9c4Sjoerg Info.Kind = SymbolKind::NonTypeTemplateParm;
368*e038c9c4Sjoerg break;
3697330f729Sjoerg // Other decls get the 'unknown' kind.
3707330f729Sjoerg default:
3717330f729Sjoerg break;
3727330f729Sjoerg }
3737330f729Sjoerg }
3747330f729Sjoerg
3757330f729Sjoerg if (Info.Kind == SymbolKind::Unknown)
3767330f729Sjoerg return Info;
3777330f729Sjoerg
3787330f729Sjoerg if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3797330f729Sjoerg if (FD->getTemplatedKind() ==
3807330f729Sjoerg FunctionDecl::TK_FunctionTemplateSpecialization) {
3817330f729Sjoerg Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
3827330f729Sjoerg Info.Properties |=
3837330f729Sjoerg (SymbolPropertySet)SymbolProperty::TemplateSpecialization;
3847330f729Sjoerg }
3857330f729Sjoerg }
3867330f729Sjoerg
3877330f729Sjoerg if (Info.Properties & (SymbolPropertySet)SymbolProperty::Generic)
3887330f729Sjoerg Info.Lang = SymbolLanguage::CXX;
3897330f729Sjoerg
3907330f729Sjoerg if (auto *attr = D->getExternalSourceSymbolAttr()) {
3917330f729Sjoerg if (attr->getLanguage() == "Swift")
3927330f729Sjoerg Info.Lang = SymbolLanguage::Swift;
3937330f729Sjoerg }
3947330f729Sjoerg
3957330f729Sjoerg return Info;
3967330f729Sjoerg }
3977330f729Sjoerg
getSymbolInfoForMacro(const MacroInfo &)3987330f729Sjoerg SymbolInfo index::getSymbolInfoForMacro(const MacroInfo &) {
3997330f729Sjoerg SymbolInfo Info;
4007330f729Sjoerg Info.Kind = SymbolKind::Macro;
4017330f729Sjoerg Info.SubKind = SymbolSubKind::None;
4027330f729Sjoerg Info.Properties = SymbolPropertySet();
4037330f729Sjoerg Info.Lang = SymbolLanguage::C;
4047330f729Sjoerg return Info;
4057330f729Sjoerg }
4067330f729Sjoerg
applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,llvm::function_ref<bool (SymbolRole)> Fn)4077330f729Sjoerg bool index::applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,
4087330f729Sjoerg llvm::function_ref<bool(SymbolRole)> Fn) {
4097330f729Sjoerg #define APPLY_FOR_ROLE(Role) \
4107330f729Sjoerg if (Roles & (unsigned)SymbolRole::Role) \
4117330f729Sjoerg if (!Fn(SymbolRole::Role)) \
4127330f729Sjoerg return false;
4137330f729Sjoerg
4147330f729Sjoerg APPLY_FOR_ROLE(Declaration);
4157330f729Sjoerg APPLY_FOR_ROLE(Definition);
4167330f729Sjoerg APPLY_FOR_ROLE(Reference);
4177330f729Sjoerg APPLY_FOR_ROLE(Read);
4187330f729Sjoerg APPLY_FOR_ROLE(Write);
4197330f729Sjoerg APPLY_FOR_ROLE(Call);
4207330f729Sjoerg APPLY_FOR_ROLE(Dynamic);
4217330f729Sjoerg APPLY_FOR_ROLE(AddressOf);
4227330f729Sjoerg APPLY_FOR_ROLE(Implicit);
4237330f729Sjoerg APPLY_FOR_ROLE(Undefinition);
4247330f729Sjoerg APPLY_FOR_ROLE(RelationChildOf);
4257330f729Sjoerg APPLY_FOR_ROLE(RelationBaseOf);
4267330f729Sjoerg APPLY_FOR_ROLE(RelationOverrideOf);
4277330f729Sjoerg APPLY_FOR_ROLE(RelationReceivedBy);
4287330f729Sjoerg APPLY_FOR_ROLE(RelationCalledBy);
4297330f729Sjoerg APPLY_FOR_ROLE(RelationExtendedBy);
4307330f729Sjoerg APPLY_FOR_ROLE(RelationAccessorOf);
4317330f729Sjoerg APPLY_FOR_ROLE(RelationContainedBy);
4327330f729Sjoerg APPLY_FOR_ROLE(RelationIBTypeOf);
4337330f729Sjoerg APPLY_FOR_ROLE(RelationSpecializationOf);
4347330f729Sjoerg APPLY_FOR_ROLE(NameReference);
4357330f729Sjoerg
4367330f729Sjoerg #undef APPLY_FOR_ROLE
4377330f729Sjoerg
4387330f729Sjoerg return true;
4397330f729Sjoerg }
4407330f729Sjoerg
applyForEachSymbolRole(SymbolRoleSet Roles,llvm::function_ref<void (SymbolRole)> Fn)4417330f729Sjoerg void index::applyForEachSymbolRole(SymbolRoleSet Roles,
4427330f729Sjoerg llvm::function_ref<void(SymbolRole)> Fn) {
4437330f729Sjoerg applyForEachSymbolRoleInterruptible(Roles, [&](SymbolRole r) -> bool {
4447330f729Sjoerg Fn(r);
4457330f729Sjoerg return true;
4467330f729Sjoerg });
4477330f729Sjoerg }
4487330f729Sjoerg
printSymbolRoles(SymbolRoleSet Roles,raw_ostream & OS)4497330f729Sjoerg void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) {
4507330f729Sjoerg bool VisitedOnce = false;
4517330f729Sjoerg applyForEachSymbolRole(Roles, [&](SymbolRole Role) {
4527330f729Sjoerg if (VisitedOnce)
4537330f729Sjoerg OS << ',';
4547330f729Sjoerg else
4557330f729Sjoerg VisitedOnce = true;
4567330f729Sjoerg switch (Role) {
4577330f729Sjoerg case SymbolRole::Declaration: OS << "Decl"; break;
4587330f729Sjoerg case SymbolRole::Definition: OS << "Def"; break;
4597330f729Sjoerg case SymbolRole::Reference: OS << "Ref"; break;
4607330f729Sjoerg case SymbolRole::Read: OS << "Read"; break;
4617330f729Sjoerg case SymbolRole::Write: OS << "Writ"; break;
4627330f729Sjoerg case SymbolRole::Call: OS << "Call"; break;
4637330f729Sjoerg case SymbolRole::Dynamic: OS << "Dyn"; break;
4647330f729Sjoerg case SymbolRole::AddressOf: OS << "Addr"; break;
4657330f729Sjoerg case SymbolRole::Implicit: OS << "Impl"; break;
4667330f729Sjoerg case SymbolRole::Undefinition: OS << "Undef"; break;
4677330f729Sjoerg case SymbolRole::RelationChildOf: OS << "RelChild"; break;
4687330f729Sjoerg case SymbolRole::RelationBaseOf: OS << "RelBase"; break;
4697330f729Sjoerg case SymbolRole::RelationOverrideOf: OS << "RelOver"; break;
4707330f729Sjoerg case SymbolRole::RelationReceivedBy: OS << "RelRec"; break;
4717330f729Sjoerg case SymbolRole::RelationCalledBy: OS << "RelCall"; break;
4727330f729Sjoerg case SymbolRole::RelationExtendedBy: OS << "RelExt"; break;
4737330f729Sjoerg case SymbolRole::RelationAccessorOf: OS << "RelAcc"; break;
4747330f729Sjoerg case SymbolRole::RelationContainedBy: OS << "RelCont"; break;
4757330f729Sjoerg case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break;
4767330f729Sjoerg case SymbolRole::RelationSpecializationOf: OS << "RelSpecialization"; break;
4777330f729Sjoerg case SymbolRole::NameReference: OS << "NameReference"; break;
4787330f729Sjoerg }
4797330f729Sjoerg });
4807330f729Sjoerg }
4817330f729Sjoerg
printSymbolName(const Decl * D,const LangOptions & LO,raw_ostream & OS)4827330f729Sjoerg bool index::printSymbolName(const Decl *D, const LangOptions &LO,
4837330f729Sjoerg raw_ostream &OS) {
4847330f729Sjoerg if (auto *ND = dyn_cast<NamedDecl>(D)) {
4857330f729Sjoerg PrintingPolicy Policy(LO);
4867330f729Sjoerg // Forward references can have different template argument names. Suppress
4877330f729Sjoerg // the template argument names in constructors to make their name more
4887330f729Sjoerg // stable.
4897330f729Sjoerg Policy.SuppressTemplateArgsInCXXConstructors = true;
4907330f729Sjoerg DeclarationName DeclName = ND->getDeclName();
4917330f729Sjoerg if (DeclName.isEmpty())
4927330f729Sjoerg return true;
4937330f729Sjoerg DeclName.print(OS, Policy);
4947330f729Sjoerg return false;
4957330f729Sjoerg } else {
4967330f729Sjoerg return true;
4977330f729Sjoerg }
4987330f729Sjoerg }
4997330f729Sjoerg
getSymbolKindString(SymbolKind K)5007330f729Sjoerg StringRef index::getSymbolKindString(SymbolKind K) {
5017330f729Sjoerg switch (K) {
5027330f729Sjoerg case SymbolKind::Unknown: return "<unknown>";
5037330f729Sjoerg case SymbolKind::Module: return "module";
5047330f729Sjoerg case SymbolKind::Namespace: return "namespace";
5057330f729Sjoerg case SymbolKind::NamespaceAlias: return "namespace-alias";
5067330f729Sjoerg case SymbolKind::Macro: return "macro";
5077330f729Sjoerg case SymbolKind::Enum: return "enum";
5087330f729Sjoerg case SymbolKind::Struct: return "struct";
5097330f729Sjoerg case SymbolKind::Class: return "class";
5107330f729Sjoerg case SymbolKind::Protocol: return "protocol";
5117330f729Sjoerg case SymbolKind::Extension: return "extension";
5127330f729Sjoerg case SymbolKind::Union: return "union";
5137330f729Sjoerg case SymbolKind::TypeAlias: return "type-alias";
5147330f729Sjoerg case SymbolKind::Function: return "function";
5157330f729Sjoerg case SymbolKind::Variable: return "variable";
5167330f729Sjoerg case SymbolKind::Field: return "field";
5177330f729Sjoerg case SymbolKind::EnumConstant: return "enumerator";
5187330f729Sjoerg case SymbolKind::InstanceMethod: return "instance-method";
5197330f729Sjoerg case SymbolKind::ClassMethod: return "class-method";
5207330f729Sjoerg case SymbolKind::StaticMethod: return "static-method";
5217330f729Sjoerg case SymbolKind::InstanceProperty: return "instance-property";
5227330f729Sjoerg case SymbolKind::ClassProperty: return "class-property";
5237330f729Sjoerg case SymbolKind::StaticProperty: return "static-property";
5247330f729Sjoerg case SymbolKind::Constructor: return "constructor";
5257330f729Sjoerg case SymbolKind::Destructor: return "destructor";
5267330f729Sjoerg case SymbolKind::ConversionFunction: return "conversion-func";
5277330f729Sjoerg case SymbolKind::Parameter: return "param";
5287330f729Sjoerg case SymbolKind::Using: return "using";
529*e038c9c4Sjoerg case SymbolKind::TemplateTypeParm: return "template-type-param";
530*e038c9c4Sjoerg case SymbolKind::TemplateTemplateParm: return "template-template-param";
531*e038c9c4Sjoerg case SymbolKind::NonTypeTemplateParm: return "non-type-template-param";
5327330f729Sjoerg }
5337330f729Sjoerg llvm_unreachable("invalid symbol kind");
5347330f729Sjoerg }
5357330f729Sjoerg
getSymbolSubKindString(SymbolSubKind K)5367330f729Sjoerg StringRef index::getSymbolSubKindString(SymbolSubKind K) {
5377330f729Sjoerg switch (K) {
5387330f729Sjoerg case SymbolSubKind::None: return "<none>";
5397330f729Sjoerg case SymbolSubKind::CXXCopyConstructor: return "cxx-copy-ctor";
5407330f729Sjoerg case SymbolSubKind::CXXMoveConstructor: return "cxx-move-ctor";
5417330f729Sjoerg case SymbolSubKind::AccessorGetter: return "acc-get";
5427330f729Sjoerg case SymbolSubKind::AccessorSetter: return "acc-set";
5437330f729Sjoerg case SymbolSubKind::UsingTypename: return "using-typename";
5447330f729Sjoerg case SymbolSubKind::UsingValue: return "using-value";
5457330f729Sjoerg }
5467330f729Sjoerg llvm_unreachable("invalid symbol subkind");
5477330f729Sjoerg }
5487330f729Sjoerg
getSymbolLanguageString(SymbolLanguage K)5497330f729Sjoerg StringRef index::getSymbolLanguageString(SymbolLanguage K) {
5507330f729Sjoerg switch (K) {
5517330f729Sjoerg case SymbolLanguage::C: return "C";
5527330f729Sjoerg case SymbolLanguage::ObjC: return "ObjC";
5537330f729Sjoerg case SymbolLanguage::CXX: return "C++";
5547330f729Sjoerg case SymbolLanguage::Swift: return "Swift";
5557330f729Sjoerg }
5567330f729Sjoerg llvm_unreachable("invalid symbol language kind");
5577330f729Sjoerg }
5587330f729Sjoerg
applyForEachSymbolProperty(SymbolPropertySet Props,llvm::function_ref<void (SymbolProperty)> Fn)5597330f729Sjoerg void index::applyForEachSymbolProperty(SymbolPropertySet Props,
5607330f729Sjoerg llvm::function_ref<void(SymbolProperty)> Fn) {
5617330f729Sjoerg #define APPLY_FOR_PROPERTY(K) \
5627330f729Sjoerg if (Props & (SymbolPropertySet)SymbolProperty::K) \
5637330f729Sjoerg Fn(SymbolProperty::K)
5647330f729Sjoerg
5657330f729Sjoerg APPLY_FOR_PROPERTY(Generic);
5667330f729Sjoerg APPLY_FOR_PROPERTY(TemplatePartialSpecialization);
5677330f729Sjoerg APPLY_FOR_PROPERTY(TemplateSpecialization);
5687330f729Sjoerg APPLY_FOR_PROPERTY(UnitTest);
5697330f729Sjoerg APPLY_FOR_PROPERTY(IBAnnotated);
5707330f729Sjoerg APPLY_FOR_PROPERTY(IBOutletCollection);
5717330f729Sjoerg APPLY_FOR_PROPERTY(GKInspectable);
5727330f729Sjoerg APPLY_FOR_PROPERTY(Local);
5737330f729Sjoerg APPLY_FOR_PROPERTY(ProtocolInterface);
5747330f729Sjoerg
5757330f729Sjoerg #undef APPLY_FOR_PROPERTY
5767330f729Sjoerg }
5777330f729Sjoerg
printSymbolProperties(SymbolPropertySet Props,raw_ostream & OS)5787330f729Sjoerg void index::printSymbolProperties(SymbolPropertySet Props, raw_ostream &OS) {
5797330f729Sjoerg bool VisitedOnce = false;
5807330f729Sjoerg applyForEachSymbolProperty(Props, [&](SymbolProperty Prop) {
5817330f729Sjoerg if (VisitedOnce)
5827330f729Sjoerg OS << ',';
5837330f729Sjoerg else
5847330f729Sjoerg VisitedOnce = true;
5857330f729Sjoerg switch (Prop) {
5867330f729Sjoerg case SymbolProperty::Generic: OS << "Gen"; break;
5877330f729Sjoerg case SymbolProperty::TemplatePartialSpecialization: OS << "TPS"; break;
5887330f729Sjoerg case SymbolProperty::TemplateSpecialization: OS << "TS"; break;
5897330f729Sjoerg case SymbolProperty::UnitTest: OS << "test"; break;
5907330f729Sjoerg case SymbolProperty::IBAnnotated: OS << "IB"; break;
5917330f729Sjoerg case SymbolProperty::IBOutletCollection: OS << "IBColl"; break;
5927330f729Sjoerg case SymbolProperty::GKInspectable: OS << "GKI"; break;
5937330f729Sjoerg case SymbolProperty::Local: OS << "local"; break;
5947330f729Sjoerg case SymbolProperty::ProtocolInterface: OS << "protocol"; break;
5957330f729Sjoerg }
5967330f729Sjoerg });
5977330f729Sjoerg }
598